//////////////////////////////////////////////////////
// Engine.cpp
//////////////////////////////////////////////////////

#include "engine.h"
#include "MyEngine.h"
#include "MyCursor.h"

int MenuOption = 0;
extern CMyEngine g_Engine;
extern MyCursor g_Cursor;


//////////////////////////////////////////////////////
// CEngine()
//////////////////////////////////////////////////////
CEngine::CEngine(char* pstrMap, int iMapType, int iDrawSector, int iSector)
{
    strcpy(m_pstrFirstMap, pstrMap);
    m_iFirstMapType = iMapType;
    m_iStartSector = iSector;
	m_iStartDrawSector = iDrawSector;
    InitGame();
    m_iAnimationTimerCount = 0;
	m_bAnimateMovement = 0;
    m_bAnimationTilesUpdated = FALSE;
    m_bFastAnimationTilesUpdated = FALSE;
    m_bFastestAnimationTilesUpdated = FALSE;
    m_bShowingPlaque = FALSE;
    m_bPlayerTurnToAttack = TRUE;
    m_bMonsterAttacking = FALSE;
    m_bRunningFromMonster = FALSE;
    m_bAskingIfSave = FALSE;
    m_bAskingIfLoad = FALSE;
    m_bAskingIfQuit = FALSE;
	m_bStartGame = FALSE;
    m_bNoMonsters = FALSE;
}

//////////////////////////////////////////////////////
// ~CEngine()
//////////////////////////////////////////////////////
CEngine::~CEngine(void)
{
    KillTimer(m_hWnd, 1);
}

//////////////////////////////////////////////////////
// SetWindowHandle()
//////////////////////////////////////////////////////
void CEngine::SetWindowHandle(HWND hWnd)
{
    m_hWnd = hWnd;
    m_Direct3D.SetWindowHandle(hWnd);
    m_Sound.SetWindowHandle(hWnd);
}

//////////////////////////////////////////////////////
// ProcessGame()
//////////////////////////////////////////////////////
void CEngine::ProcessGame(void)
{
    HRESULT hResult = m_Direct3D.GetDevice()->TestCooperativeLevel();
    if (hResult == D3DERR_DEVICELOST)
        m_bGamePaused = TRUE;
    else if (hResult == D3DERR_DEVICENOTRESET)
    {
        ResetDirect3D();
        m_bGamePaused = FALSE;
    }
    else
    {
		if (GetStartGame() == false)
		{
			SetGameState(TitleScreen);
			PaintTitleScreen();
		}
		else
		{
			RespondToPlayerLocation();
			MoveNPCs();
			PaintBackBuffer();
		}
    }
}

//////////////////////////////////////////////////////
// SetStartGame()
//////////////////////////////////////////////////////
void CEngine::SetStartGame(bool begin)
{
	m_bStartGame = begin;			//11-30-06
}

//////////////////////////////////////////////////////
// GetStartGame()
//////////////////////////////////////////////////////
bool CEngine::GetStartGame()
{
	return m_bStartGame;			//11-30-06
}

//////////////////////////////////////////////////////
// SetGameState() 11-30-06
//////////////////////////////////////////////////////
void CEngine::SetGameState(int GState)
{
	CurrentGameState = GState;
}

//////////////////////////////////////////////////////
// GetGameState() 11-30-06
//////////////////////////////////////////////////////
int CEngine::GetGameState()
{
	return CurrentGameState;
}
//////////////////////////////////////////////////////
// HandleKeys()
//////////////////////////////////////////////////////
void CEngine::HandleKeys(WPARAM wParam)
{
	/*  switch statement added 11/30/06, this will switch what the keys do
		if gamestate = title screen, then the keys will refer to the title screen
		if gamestate = playgame then keys will respond for playing the game
	*/
	switch(GetGameState())
	{
	case TitleScreen:
		switch(wParam)
		{
			case VK_ESCAPE:
				break;
			case VK_UP:
				HandleUpArrowInMenu();
				break;
			case VK_DOWN:
				HandleDownArrowInMenu();
				break;
			case VK_RETURN:
				HandleEnterInMenu();
				break;
		}
		
	break;
	
	case PlayGame:
	
			switch(wParam)
			{
			case VK_UP:
				HandleUpArrow();
				break;
			case VK_DOWN:
				HandleDownArrow();
				break;
			case VK_LEFT:
				HandleLeftArrow();
				break;
			case VK_RIGHT:
				HandleRightArrow();
				break;
			case VK_RETURN:
				HandleEnter();
				break;
			case VK_ESCAPE:
				HandleEscape();
				break;
			case VK_SPACE:
				HandleSpace();
				break;
			case 73: // I
				ShowInventory();
				break;
			case 65: // A
				HandleA();
				break;
			case 80: // P
				TakePotion();
				break;
			case 82: // R
				RunFromMonster();
				break;
			case 83: // S
				HandleS();
				break;
			case 76: // L
				HandleL();
				break;
			case 78: // N
				HandleN();
				break;
			case 89: // Y
				HandleY();
				break;
			case 77: // M
				ToggleMonsters();
				break;
			case 75: // K
				GetKeys();
				break;
			case 71: // G
				GetGold();
				break;
			case 69: // E
				GetExperience();
				break;
			case 72: // H
				GetHitPoints();
				break;
			}

	break;

	case BattleMenu:
		
		switch(wParam)
		{
		case VK_ESCAPE:
				HandleEscapeBattleMenu();
				break;
		case 65: // A
				HandleABattleMenu();
				break;
		case 77: // M
				HandleMBattleMenu();
				break;
		}
		break;

	case BattleMenuMoveOnly:

		switch(wParam)
		{
		case VK_ESCAPE:
				HandleEscapeBattleMenu();
				break;
		case 77: // M
				HandleMBattleMenu();
				break;
		}
		break;

	case BattleMenuAttackOnly:

		switch(wParam)
		{
		case VK_ESCAPE:
				HandleEscapeBattleMenu();
				break;
		case 65: // A
				HandleABattleMenu();
				break;

		case 83: //S
				HandleSBattleMenu();
				break;
		}
		break;

	case AttackCursor:
	case AttackCursorDone:

		switch(wParam)
		{
		case VK_ESCAPE:
				HandleEscapeBattleMenu();
				break;
		case VK_UP:
				HandleUpArrowBattleMenu();
				break;
		case VK_DOWN:
				HandleDownArrowBattleMenu();
				break;
		case VK_LEFT:
				HandleLeftArrowBattleMenu();
				break;
		case VK_RIGHT:
				HandleRightArrowBattleMenu();
				break;
		case VK_RETURN:
				HandleEnter();
				break;
		}
		break;

	case MoveCursor:
	case MoveCursorDone:
		
		switch(wParam)
		{
		case VK_ESCAPE:
			HandleEscapeBattleMenu();
			break;
		case VK_UP:
			HandleUpArrowBattleMenu();
			break;
		case VK_DOWN:
			HandleDownArrowBattleMenu();
			break;
		case VK_LEFT:
			HandleLeftArrowBattleMenu();
			break;
		case VK_RIGHT:
			HandleRightArrowBattleMenu();
			break;
		case VK_RETURN:
			HandleEnter();
			break;
		}
		break;

	case AttackDecide:
	case AttackDecideDone:

		switch(wParam)
		{
		case VK_ESCAPE:
			HandleEscapeBattleMenu();
			break;
		case VK_RETURN:
			HandleEnter();
			break;
		}
		break;

	case MoveDecide:
	case MoveDecideDone:

		switch(wParam)
		{
		case VK_ESCAPE:
			HandleEscapeBattleMenu();
			break;
		case VK_RETURN:
			HandleEnter();
			break;
		}
		break;

	case AttackRead:
	case AttackReadDone:

		switch(wParam)
		{
		case VK_ESCAPE:
			HandleEscapeBattleMenu();
			break;
		case VK_RETURN:
			HandleEnter();
			break;
		}
		break;

	case FacingDecide:
		switch(wParam)
		{
		case VK_UP:
			HandleUpArrowBattleMenu();
			break;
		case VK_DOWN:
			HandleDownArrowBattleMenu();
			break;
		case VK_LEFT:
			HandleLeftArrowBattleMenu();
			break;
		case VK_RIGHT:
			HandleRightArrowBattleMenu();
			break;
		case VK_RETURN:
			HandleEnter();
			break;
		}
		break;
	}
}

//////////////////////////////////////////////////////
// GetCDirect3DObj()
//////////////////////////////////////////////////////
CDirect3D* CEngine::GetCDirect3DObj()
{
    return &m_Direct3D;
}

//////////////////////////////////////////////////////
// InitGame()
//////////////////////////////////////////////////////
void CEngine::InitGame()
{
	int SecPos;
	int c_ColumnRandom;
	int c_RowRandom;
	bool GoodPos;

	GoodPos = true;

    DeleteTempFiles();
    OpenMapFiles(m_pstrFirstMap, TRUE);
    m_iCurrentMap = m_iFirstMapType;
    m_Player.SetGold(25);
    m_Player.SetHitPoints(10);
    m_Player.SetMaxHitPoints(10);
    m_Player.SetKeys(1);
    m_Player.SetSector(m_iStartSector);
    srand((unsigned)time(NULL));
    m_Player.SetMaxHitPoints(10);

	//add monster 
	for(int i = 0; i < MaxMonsters; i++)
	{
		mon[i].SetMonsterDead(false);
		mon[i].SetCurrentFrame(MYMONSTERIDLEFRAME);
		mon[i].SetRespawnCounter(20);
		mon[i].SetRespawn(false);
		mon[i].SetHitPoints(1);
		mon[i].SetMaxHitPoints(1);


		do
		{
			// randomize monster sector?
			c_ColumnRandom = rand() % 10;
			c_RowRandom = rand() % 6;
			
			SecPos = 727 + c_ColumnRandom + (MAPCOLUMNCOUNT) * c_RowRandom;
			GoodPos = true;
			if(SecPos != m_Player.GetSector())
			{

				for(int j = 0; j < i; j++)
				{
					if(SecPos == mon[j].GetSector())
					{
						GoodPos = false;
					}
				}
			}
			else
			{
				GoodPos = false;
			}

			if(GoodPos)
				mon[i].SetSector(SecPos);

		}while(GoodPos == false);
		

		// ~Cai 3/07/07 GDC Day ONE!!! I'M SCARED OUTTA MY WITS!
		
	}
}

//////////////////////////////////////////////////////
// GetPlayer()
//////////////////////////////////////////////////////
CPlayer* CEngine::GetPlayer()
{
    return &m_Player;
}

//////////////////////////////////////////////////////
// GetCurrentMap()
//////////////////////////////////////////////////////
int CEngine::GetCurrentMap()
{
    return m_iCurrentMap;
}

//////////////////////////////////////////////////////
// SetCurrentMap()
//////////////////////////////////////////////////////
void CEngine::SetCurrentMap(int map)
{
    m_iCurrentMap = map;
}

// - do we USE getsectors? ~Cai 1/28/07
//////////////////////////////////////////////////////
// GetSectors()
//////////////////////////////////////////////////////
char* CEngine::GetSectors()
{
    return (char*)&m_Sectors;
}

//////////////////////////////////////////////////////
// OpenMapFiles()
//////////////////////////////////////////////////////
void CEngine::OpenMapFiles(char* fName, BOOL bNewGame)
{
    char fileName[_MAX_PATH];
    strcpy(m_pstrCurrentMapFile, fName);
    strcpy(fileName, fName);
    ConstructFileName(fileName, bNewGame);
    ReadMapFile(fileName);
    ReadPeopleFile(fileName);
    ReadContainerFile(fileName);
    ReadDoorFile(fileName);
}

//////////////////////////////////////////////////////
// ConstructFileName()
//////////////////////////////////////////////////////
void CEngine::ConstructFileName(char* fileName, BOOL bNewGame)
{
    char NewMapFileName[_MAX_PATH];
    char TempMapFileName[_MAX_PATH];
    strcpy(NewMapFileName, "Maps\\");
    strcpy(&NewMapFileName[5], fileName);
    strcpy(TempMapFileName, "Temp\\");
    strcpy(&TempMapFileName[5], fileName);

    if (bNewGame)
        strcpy(fileName, NewMapFileName);
    else   
    {
        std::ifstream testFile(TempMapFileName, std::ios::binary);
        if (testFile.fail())
            strcpy(fileName, NewMapFileName);
        else
	        strcpy(fileName, TempMapFileName);
        testFile.close();
    }
}

//////////////////////////////////////////////////////
// ReadPeopleFile()
//////////////////////////////////////////////////////
void CEngine::ReadPeopleFile(char*fileName)
{
    char m_peopleFileName[_MAX_PATH];
    char buf[256];
    strcpy(m_peopleFileName, fileName);
    strcpy(&m_peopleFileName[strlen(m_peopleFileName)], ".peo");
    std::ifstream m_peopleFile(m_peopleFileName, std::ios::binary);

    // Get the number of m_people in the file.
    GetStringFromFile(m_peopleFile, buf);
    m_People.SetPersonCount(atoi(buf));

    for (int person=0; person<m_People.GetPersonCount(); ++person)
    {
        // Get the person's name.
        GetStringFromFile(m_peopleFile, buf);
        m_People.GetPerson(person)->SetName(buf);

        // Get the person's location.
        GetStringFromFile(m_peopleFile, buf);
        m_People.GetPerson(person)->SetSector(atoi(buf));

        // Get the person's move capability.
        GetStringFromFile(m_peopleFile, buf);

        if (buf[1] == 'F')
            m_People.GetPerson(person)->SetCanMove(FALSE);
        else
            m_People.GetPerson(person)->SetCanMove(TRUE);

        // Get the person's tile number.
        GetStringFromFile(m_peopleFile, buf);
        m_People.GetPerson(person)->SetTile(atoi(buf));
    }
    m_peopleFile.close();
}

//////////////////////////////////////////////////////
// ReadContainerFile()
//////////////////////////////////////////////////////
void CEngine::ReadContainerFile(char* fileName)
{
    char ContainerFileName[_MAX_PATH];
    char buf[256];
    strcpy(ContainerFileName, fileName);
    strcpy(&ContainerFileName[strlen(ContainerFileName)], ".itm");
    std::ifstream ContainerFile(ContainerFileName, std::ios::binary);

    // Get the number of containers in the file.
    GetStringFromFile(ContainerFile, buf);
    m_Containers.SetContainerCount(atoi(buf));

    for (int iContainer=0; iContainer<m_Containers.GetContainerCount();
             ++iContainer)
    {
        // Get the amount of gold.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetGold(atoi(buf));

        // Get the number of keys.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetKeys(atoi(buf));

        // Get the number of potions.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetPotion(atoi(buf));

        // Get the armor type.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetArmor(atoi(buf));

        // Get the weapon type.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetWeapon(atoi(buf));

        // Get the locked setting.
        GetStringFromFile(ContainerFile, buf);
        if (buf[1] == 'F')
            m_Containers.GetContainer(iContainer)->SetLocked(FALSE);
        else
            m_Containers.GetContainer(iContainer)->SetLocked(TRUE);

        // Get the item's sector.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetSector(atoi(buf));

        // Get the item's tile number.
        GetStringFromFile(ContainerFile, buf);
        m_Containers.GetContainer(iContainer)->SetTile(atoi(buf));
    }
    ContainerFile.close();
}

//////////////////////////////////////////////////////
// ReadDoorFile()
//////////////////////////////////////////////////////
void CEngine::ReadDoorFile(char*fileName)
{
    char doorFileName[_MAX_PATH];
    char buf[256];
    strcpy(doorFileName, fileName);
    strcpy(&doorFileName[strlen(doorFileName)], ".dor");
    std::ifstream doorFile(doorFileName, std::ios::binary);

    // Get the number of doors in the file.
    GetStringFromFile(doorFile, buf);
    m_Doors.SetDoorCount(atoi(buf));

    for (int door=0; door<m_Doors.GetDoorCount(); ++door)
    {
        // Get the secret setting.
        GetStringFromFile(doorFile, buf);
        if (buf[1] == 'F')
            m_Doors.GetDoor(door)->SetSecret(FALSE);
        else
            m_Doors.GetDoor(door)->SetSecret(TRUE);

        // Get the locked setting.
        GetStringFromFile(doorFile, buf);
        if (buf[1] == 'F')
            m_Doors.GetDoor(door)->SetLocked(FALSE);
        else
            m_Doors.GetDoor(door)->SetLocked(TRUE);

        // Get the item's sector.
        GetStringFromFile(doorFile, buf);
        m_Doors.GetDoor(door)->SetSector(atoi(buf));

        // Get the item's tile number.
        GetStringFromFile(doorFile, buf);
        m_Doors.GetDoor(door)->SetTile(atoi(buf));
    }
    doorFile.close();
}

//////////////////////////////////////////////////////
// ReadMapFile()
//////////////////////////////////////////////////////
void CEngine::ReadMapFile(char* fileName)
{
    std::ifstream mapFile(fileName, std::ios::binary);
    mapFile.read((char*)&m_byMapType, 1);
    mapFile.read(m_Sectors, sizeof m_Sectors);
	// to set the a_Sectors and h_Sectors
	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		a_Sectors[CaiCount] = 13;
	}
	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		h_Sectors[CaiCount] = 13;
	}
	// ~Cai 1/28/07
    mapFile.close();
}

//////////////////////////////////////////////////////
// GetStringFromFile()
//////////////////////////////////////////////////////
void CEngine::GetStringFromFile(std::ifstream& str, char* buf)
{
      int i = 0;
      char c;
      str.read(&c, 1);
      while (c != 13)
      {
          buf[i++] = c;
          str.read(&c, 1);
      }
      str.read(&c, 1);
      buf[i] = 0;
}

//////////////////////////////////////////////////////
// PaintBackBuffer()
//////////////////////////////////////////////////////
void CEngine::PaintBackBuffer()
{
    PaintBackground();
    //PaintPlayer(m_Direct3D.GetBackBuffer());
    if (m_bShowingPlaque)
        PaintPlaque();
    if (m_bMonsterAttacking)
    {
        PaintBattlePlaque();
    }
    m_Direct3D.GetDevice()->Present(NULL, NULL, NULL, NULL);
}

//////////////////////////////////////////////////////
// PaintTitleScreen()
//////////////////////////////////////////////////////
void CEngine::PaintTitleScreen()
{
	IDirect3DSurface8* pBackBuffer = NULL;
	IDirect3DSurface8* pDisplay;

	switch(MenuOption)
	{
	case StartGame:
			pDisplay = m_Direct3D.GetTitleScreen();
			break;
	case Options:
			pDisplay = m_Direct3D.GetTitleScreenOptions();
			break;
	case QuitGame:
			pDisplay = m_Direct3D.GetTitleScreenQuit();
			break;
	}


	HRESULT hResult = m_Direct3D.GetDevice()->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
	if(FAILED(hResult))
	{
		//strcpy(m_Direct3D.m_szErrorMsg, "Error retrieving BackBuffer for Title Screen.");
		PostQuitMessage(WM_QUIT);
	}

	hResult = m_Direct3D.GetDevice()->CopyRects(pDisplay, NULL, 0, pBackBuffer, NULL);
	if(FAILED(hResult))
	{
		//strcpy(m_Direct3D.m_szErrorMsg, "Error creating rect in PaintTitleScreen.");
		PostQuitMessage(WM_QUIT);
	}

	PaintTitleScreenCursor(); //function call to paint cursor

}
//////////////////////////////////////////////////////
// PaintTitleScreenCursor()
//////////////////////////////////////////////////////
void CEngine::PaintTitleScreenCursor()
{
	//Paints the Cursor on the title screen, where it belongs, depending on what option
	//is currently picked using the enum MenuOption

    unsigned char *vb_vertices;
    IDirect3DVertexBuffer8* pSquare;
	int x;

	switch (MenuOption)
	{
	case StartGame:
		x = 0;
		break;
	case Options:
		x = 100;
		break;
	case QuitGame:
		x = 200;
		break;
	}

		vertex m_square_vertices[] =
		{
			{ 470.0f,(float)x + 300.0f, 0.0f, 1.0f, 0.0f, 1.0f },  /* Lower left corner */
			{ 470.0f,(float)x + 236.0f,  0.0f, 1.0f, 0.0f, 0.0f }, /* Upper left corner */
			{ 534.0f,(float)x + 300.0f, 0.0f, 1.0f, 1.0f, 1.0f },  /* Lower right corner */
			{ 534.0f,(float)x + 236.0f,  0.0f, 1.0f, 1.0f, 0.0f }  /* Upper right corner */
		};
	
		

    // Create and load the vertex buffer.
    HRESULT hResult = m_Direct3D.GetDevice()->
        CreateVertexBuffer(4*sizeof(vertex),D3DUSAGE_WRITEONLY,
        D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &pSquare);
    hResult = pSquare->Lock(0, 0, &vb_vertices, 0);
    memcpy(vb_vertices, m_square_vertices, sizeof(m_square_vertices));
    pSquare->Unlock();

    // Display the texture.
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_SRCBLEND, 
        D3DBLEND_SRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_DESTBLEND, 
        D3DBLEND_INVSRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    if(SUCCEEDED(m_Direct3D.GetDevice()->BeginScene()))
    { 
        m_Direct3D.GetDevice()->SetVertexShader(D3D8T_CUSTOMVERTEX);
        m_Direct3D.GetDevice()->SetStreamSource(0, pSquare, sizeof(vertex));
        m_Direct3D.GetDevice()->SetTexture(0, m_Direct3D.GetTitleScreenCursor());
		m_Direct3D.GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
        m_Direct3D.GetDevice()->EndScene();
		m_Direct3D.GetDevice()->Present( NULL, NULL, NULL, NULL);
    }
    pSquare->Release();
}
//////////////////////////////////////////////////////
// PaintBackground()
//////////////////////////////////////////////////////
void CEngine::PaintBackground()
{
    int LowVisibleCol;
    int HiVisibleCol;
    int LowVisibleRow;
    int HiVisibleRow;

    SetVisibleColsRows(LowVisibleCol, HiVisibleCol, 
        LowVisibleRow, HiVisibleRow);
    m_Direct3D.GetDevice()->Clear(0, NULL, D3DCLEAR_TARGET, 
        D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

    int DstRow = 0;

	// 8 long, 7 short
	// 1-18-07

	///////////////

	bool longrow = true,
		 newsctcount;
	//int c_size = 113;
	int newStart;

	newStart = m_iStartDrawSector;

	newsctcount = true;

	///////////////

	//Cai 1/29/07
	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		a_Sectors[CaiCount] = 13;
	}
	a_Sectors[m_Player.GetSector()] = m_Player.GetCurrentFrame();
	
	for(int i = 0; i < MaxMonsters; i++)
	{
		a_Sectors[mon[i].GetSector()] = mon[i].GetCurrentFrame();
	}

	//Cai 2/6/07
	/*
	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		h_Sectors[CaiCount] = 0;
	}
	move_highlights();
	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		if(h_Sectors[CaiCount] != 0)
		{
			h_Sectors[CaiCount] = 16;
		}
		else
		{
			h_Sectors[CaiCount] = 13;
		}
	}
	*/

	for (int SrcRow = LowVisibleRow; SrcRow <= HiVisibleRow; ++SrcRow)
    {
        int DstCol = 0;
        for (int SrcCol = LowVisibleCol; SrcCol <= HiVisibleCol; ++SrcCol)
        {
            int iSector = ColumnRow2Sector(newStart, longrow, newsctcount);
            int TileNumber = m_Sectors[iSector];
			int TileNumber_H = h_Sectors[iSector];
			if(iSector == g_Cursor.GetSector())
			{
				TileNumber_H = 15;
			}
			int TileNumber_A = a_Sectors[iSector];
            if (IsDoor(iSector))
                TileNumber = CheckForSecretDoor(TileNumber, iSector);
            IDirect3DSurface8* backbuf = m_Direct3D.GetBackBuffer();
            PlaceTile(m_Direct3D.GetBackBuffer(), 
              m_Direct3D.GetCurrentTileSurface(), TileNumber, DstCol, DstRow,
              COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
			///////////////////////// Actor and Highlight drawing will occur here
			// ~Cai 1/28/07
			
			if(TileNumber_H != 13 && TileNumber_H != 15)
			{
				PlaceTile(m_Direct3D.GetBackBuffer(), 
				m_Direct3D.GetCurrentTileSurface(), TileNumber_H, DstCol, DstRow,
				COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
			}

			if(m_bAnimateMovement != 0)
			{
				if(TileNumber_H == 15)
				{
					DrawMovingDude(DstCol, DstRow, longrow);
				}
			}
			else
			{
				if(TileNumber_H != 13)
				{
					PlaceTile(m_Direct3D.GetBackBuffer(), 
					m_Direct3D.GetCurrentTileSurface(), TileNumber_H, DstCol, DstRow,
					COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);   
				}
			}

			/*if(TileNumber_A != 13)
			{
				PlaceTile(m_Direct3D.GetBackBuffer(), 
				m_Direct3D.GetCurrentTileSurface(), TileNumber_A, DstCol, DstRow,
				COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
			}*/
			//
			/////////////////////////
            int person;
            if (SectorHasPerson(iSector, person))
                PlaceTile(m_Direct3D.GetBackBuffer(), 
                  m_Direct3D.GetCurrentTileSurface(), 
                  m_People.GetPerson(person)->GetTile(), DstCol, DstRow,
                  COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
            ++DstCol;
        }
        DstRow = DstRow + 1;
    }
	
	DstRow = 0;
	longrow = true;
	//int c_size = 113;

	newStart = m_iStartDrawSector;

	newsctcount = true;

	for (int SrcRow = LowVisibleRow; SrcRow <= HiVisibleRow; ++SrcRow)
    {
        int DstCol = 0;
        for (int SrcCol = LowVisibleCol; SrcCol <= HiVisibleCol; ++SrcCol)
        {
            int iSector = ColumnRow2Sector(newStart, longrow, newsctcount);

			int TileNumber_A = a_Sectors[iSector];

			if(TileNumber_A != 13)
			{
				PlaceTile(m_Direct3D.GetBackBuffer(), 
				m_Direct3D.GetCurrentTileSurface(), TileNumber_A, DstCol, DstRow,
				COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
			}
            ++DstCol;
        }
        DstRow = DstRow + 1;
    }
	

	/*
    for (int SrcRow = LowVisibleRow; SrcRow <= HiVisibleRow; ++SrcRow)
    {
        int DstCol = 0;
        for (int SrcCol = LowVisibleCol; SrcCol <= HiVisibleCol; ++SrcCol)
        {
            int iSector = ColumnRow2Sector(SrcCol, SrcRow, MAPCOLUMNCOUNT, CAIcount);
            int TileNumber = m_Sectors[iSector];
            if (IsDoor(iSector))
                TileNumber = CheckForSecretDoor(TileNumber, iSector);
            IDirect3DSurface8* backbuf = m_Direct3D.GetBackBuffer();
            PlaceTile(m_Direct3D.GetBackBuffer(), 
              m_Direct3D.GetCurrentTileSurface(), TileNumber, DstCol, DstRow,
              COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
            int person;
            if (SectorHasPerson(iSector, person))
                PlaceTile(m_Direct3D.GetBackBuffer(), 
                  m_Direct3D.GetCurrentTileSurface(), 
                  m_People.GetPerson(person)->GetTile(), DstCol, DstRow,
                  COLUMNSINTILEFILE, MAPCOLUMNCOUNT, TILESIZE, XOFFSET, YOFFSET);
            ++DstCol;
        }
        DstRow = DstRow + 1;
    }
	*/
}

//////////////////////////////////////////////////////
// PlaceTile()
//////////////////////////////////////////////////////
HRESULT CEngine::PlaceTile(IDirect3DSurface8* pBackBuffer,
    IDirect3DSurface8* pTileSurface, int TileNumber,
    int DstCol, int DstRow, int numTileCols, int numMapCols,
    int tileSize, int xOffset, int yOffset)
{
	HRESULT hResult DS_OK;


    POINT DstPoint;

    DstPoint.x = Column2X(DstCol, DstRow, tileSize, numMapCols) + xOffset;
    DstPoint.y = Row2Y(DstRow, tileSize) + yOffset;


	m_Direct3D.InitBlit();

	// Set up Blit parameters.
	D3DXVECTOR2 centre(TILESIZE / 2, TILESIZE / 2);
	D3DXVECTOR2 scaling(1.0f, 1.0f);
	float angle = 0;
	D3DCOLOR colour = 0xFFFFFFFF;

	// Draw sprites.
	m_Direct3D.Blit(m_Direct3D.Getg_lpTextures(TileNumber), &DstPoint, &centre, &scaling, angle, colour);

	return hResult;
}
//////////////////////////////////////////////////////
// SetVisibleColsRows()
//////////////////////////////////////////////////////
void CEngine::SetVisibleColsRows(int& LowVisibleCol, int& HiVisibleCol,
    int& LowVisibleRow, int& HiVisibleRow)
{
    int PlayerMapCol = Sector2Column(m_Player.GetSector(), MAPCOLUMNCOUNT);
    int PlayerMapRow = Sector2Row(m_Player.GetSector(), MAPCOLUMNCOUNT);
    LowVisibleCol = PlayerMapCol - NORMALVISIBLEPLAYERCOL;
    HiVisibleCol = PlayerMapCol + NORMALVISIBLEPLAYERCOL;
    LowVisibleRow = PlayerMapRow - NORMALVISIBLEPLAYERROW;
    HiVisibleRow = PlayerMapRow + NORMALVISIBLEPLAYERROW;

    if (PlayerMapCol < NORMALVISIBLEPLAYERCOL)
    {
        LowVisibleCol = 0;
        HiVisibleCol = 8;
    }
    else if (PlayerMapCol > 38)
    {
        LowVisibleCol = 33;
        HiVisibleCol = 41;
    }

    if (PlayerMapRow < NORMALVISIBLEPLAYERROW)
    {
        LowVisibleRow = 0;
        HiVisibleRow = 24;
    }
    else if (PlayerMapRow > 31)
    {
        LowVisibleRow = 17;
        HiVisibleRow = 41;
    }
}

//////////////////////////////////////////////////////
// PaintPlayer()
//////////////////////////////////////////////////////
void CEngine::PaintPlayer(IDirect3DSurface8* pBackBuffer)
{
    int PlayerMapCol = Sector2Column(m_Player.GetSector(), MAPCOLUMNCOUNT);
    int PlayerMapRow = Sector2Row(m_Player.GetSector(), MAPCOLUMNCOUNT);
    int FinalVisiblePlayerCol = NORMALVISIBLEPLAYERCOL;
    int FinalVisiblePlayerRow = NORMALVISIBLEPLAYERROW;
    if (PlayerMapCol < NORMALVISIBLEPLAYERCOL)
    {
        FinalVisiblePlayerCol = NORMALVISIBLEPLAYERCOL - 
            (NORMALVISIBLEPLAYERCOL - PlayerMapCol);
    }
    else if (PlayerMapCol > 32)
    {
        FinalVisiblePlayerCol = 
            VISIBLECOLUMNCOUNT -((MAPCOLUMNCOUNT-1)-PlayerMapCol)-1;
    }

    if (PlayerMapRow < NORMALVISIBLEPLAYERROW)
    {
        FinalVisiblePlayerRow = NORMALVISIBLEPLAYERROW - 
            (NORMALVISIBLEPLAYERROW - PlayerMapRow);
    }
    else if (PlayerMapRow > 34)
    {
        FinalVisiblePlayerRow = 
            VISIBLEROWCOUNT -((MAPROWCOUNT-1)-PlayerMapRow)-1;
    }


	//new stuff for textures
    unsigned char *vb_vertices;
    IDirect3DVertexBuffer8* pSquare;
	int y = Row2Y(FinalVisiblePlayerRow, TILESIZE) + YOFFSET;
	int x = Column2X(FinalVisiblePlayerCol, FinalVisiblePlayerRow, TILESIZE, MAPCOLUMNCOUNT) + XOFFSET;

		vertex m_square_vertices[] =
		{
			{ (float)x + 0.0f,(float)y + 100.0f, 0.0f, 1.0f, 0.0f, 1.0f },  /* Lower left corner */
			{ (float)x + 0.0f,(float)y + 0.0f,  0.0f, 1.0f, 0.0f, 0.0f }, /* Upper left corner */
			{ (float)x + 100.0f,(float)y + 100.0f, 0.0f, 1.0f, 1.0f, 1.0f },  /* Lower right corner */
			{ (float)x + 100.0f,(float)y + 0.0f,  0.0f, 1.0f, 1.0f, 0.0f }  /* Upper right corner */
		};


    // Create and load the vertex buffer.
    HRESULT hResult = m_Direct3D.GetDevice()->
        CreateVertexBuffer(4*sizeof(vertex),D3DUSAGE_WRITEONLY,
        D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &pSquare);
    hResult = pSquare->Lock(0, 0, &vb_vertices, 0);
    memcpy(vb_vertices, m_square_vertices, sizeof(m_square_vertices));
    pSquare->Unlock();

    // Display the texture.
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_SRCBLEND, 
        D3DBLEND_SRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_DESTBLEND, 
        D3DBLEND_INVSRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    if(SUCCEEDED(m_Direct3D.GetDevice()->BeginScene()))
    { 
        m_Direct3D.GetDevice()->SetVertexShader(D3D8T_CUSTOMVERTEX);
        m_Direct3D.GetDevice()->SetStreamSource(0, pSquare, sizeof(vertex));
        m_Direct3D.GetDevice()->SetTexture(0, m_Direct3D.GetPlayerTile());
		m_Direct3D.GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
        m_Direct3D.GetDevice()->EndScene();
    }
    pSquare->Release();

}

/*
//////////////////////////////////////////////////////
// ColumnRow2Sector()
//////////////////////////////////////////////////////
int CEngine::ColumnRow2Sector(int c, int r, int numCols, int)
{
    return r * numCols + c;
}
*/

//////////////////////////////////////////////////////
// CAI'S VERSION ColumnRow2Sector()
//////////////////////////////////////////////////////
int CEngine::ColumnRow2Sector(int &newStart, bool &longrow, bool &newsctcount)
{
		int sector;

		static int sctcount = 0;
		if(newsctcount)
		{
			sctcount = 0;
			newsctcount = false;
		}
		sector = newStart;

		//increments diagonally
		sector = sector + (sctcount * (-(MAPCOLUMNCOUNT - 1)));

		if (sctcount == 8 && longrow == true)
		{
			newStart = sector - (sctcount * (-(MAPCOLUMNCOUNT - 1))) + 1;
			sctcount = 0;
			longrow = false;
		}
		else if (sctcount == 8 && longrow == false)
		{
			newStart = sector - (sctcount * (-(MAPCOLUMNCOUNT - 1))) + MAPCOLUMNCOUNT;
			sctcount = 0;
			longrow = true;
		}
		else
		{
			sctcount++;
		}

		return sector;
}

//////////////////////////////////////////////////////
// Column2X()
//////////////////////////////////////////////////////
int CEngine::Column2X(int col, int row, int tileSize, int numCols)
{
	if (row % 2 == 0)
		return ((col - ((int)((col / numCols)) * numCols)) * tileSize);
	else
		return (col - ((int)((col / numCols)) * numCols)) * tileSize + 50;
}

//////////////////////////////////////////////////////
// DudeColumn2X()
//////////////////////////////////////////////////////
int CEngine::DudeColumn2X(int col, bool longrow, int tileSize, int numCols)
{
	if (longrow == true)
		return ((col - ((int)((col / numCols)) * numCols)) * tileSize);
	else
		return (col - ((int)((col / numCols)) * numCols)) * tileSize + 50;
}

//////////////////////////////////////////////////////
// Row2Y()
//////////////////////////////////////////////////////
int CEngine::Row2Y(int r, int tileSize)
{
		return (r * (tileSize / 4));
}

//////////////////////////////////////////////////////
// TileNumber2SourceX()
//////////////////////////////////////////////////////
int CEngine::TileNumber2SourceX(int TileNumber, int numCols, int tileSize)
{
    return (TileNumber - ((int)(TileNumber / numCols))
        * numCols) * tileSize;
}

//////////////////////////////////////////////////////
// TileNumber2SourceY()
//////////////////////////////////////////////////////
int CEngine::TileNumber2SourceY(int TileNumber, int numCols, int tileSize)
{
    return ((int)(TileNumber / numCols)) * tileSize;
}

//////////////////////////////////////////////////////
// Sector2Column()
//////////////////////////////////////////////////////
int CEngine::Sector2Column(int iSector, int numCols)
{
    int result = (iSector % numCols) - (m_iStartDrawSector % numCols);
    return result; 
}

//////////////////////////////////////////////////////
// Sector2Row()
//////////////////////////////////////////////////////
int CEngine::Sector2Row(int iSector, int numCols)
{
    return (int)(iSector / numCols) - (int)(m_iStartDrawSector / numCols);
}
//////////////////////////////////////////////////////
// HandleUpArrowInMenu()
//////////////////////////////////////////////////////
void CEngine::HandleUpArrowInMenu()
{
	MenuOption = MenuOption - 1;
	if (MenuOption == -1)
		MenuOption = Max - 1;
}

//////////////////////////////////////////////////////
// HandleDownArrowInMenu()
//////////////////////////////////////////////////////
void CEngine::HandleDownArrowInMenu()
{
	MenuOption = MenuOption + 1;
	if (MenuOption == Max)
		MenuOption = 0;
    
}

//////////////////////////////////////////////////////
// HandleEnterInMenu()
//////////////////////////////////////////////////////
void CEngine::HandleEnterInMenu()
{
	
	switch(MenuOption)
	{
		case StartGame:
			m_Direct3D.CreateNonMapSurfaces();
			m_Direct3D.CreateTrainingGroundsSurfaces();
			m_Direct3D.SetCurrentTileSurface(m_Direct3D.GetTrainingGroundsSurfaces());
			SetGameState(PlayGame);
			SetStartGame(true);
			g_Engine.GetCDirectSoundObj()->StopMusic(TitleScreenMusic);
			g_Engine.GetCDirectSoundObj()->PlayMusic(TrainingGroundsMusic);
			m_Direct3D.CleanUpTitleScreen();
			 
		break;
		case Options:
		break;
		case QuitGame:
			PostQuitMessage(WM_QUIT);
		break;

	}
    
}

//////////////////////////////////////////////////////
// HandleUpArrow()
//////////////////////////////////////////////////////
void CEngine::HandleUpArrow()
{
    if (m_bMonsterAttacking) return;
    if (IsShowingPlaque()) return;
    int iTargetSector = m_Player.GetSector() - MAPCOLUMNCOUNT;
    if (!m_bNoMonsters)
    {
        BOOL bFoughtMonster = CheckForAndHandleBattle();
        if (bFoughtMonster) return;
    }
    BOOL bHandledNPC = CheckForAndHandleNPC(iTargetSector);
    if (bHandledNPC) return;
    BOOL bHandledContainer = 
        CheckForAndHandleContainer(iTargetSector);
    if (bHandledContainer)
        return;
    int iDoorStatus = 
        CheckForAndHandleDoor(iTargetSector);
    //if (iDoorStatus == NODOOR || iDoorStatus == DOORUNLOCKED)
    
	//~Cai 1/29/07
	if(g_Cursor.GetSector() / MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector()-MAPCOLUMNCOUNT] != 13)
		{
			if(	
			/*
				m_iStartDrawSector - 328 == m_Player.GetSector() ||
				(m_iStartDrawSector - 287 <= m_Player.GetSector() && m_iStartDrawSector - 285 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 246 <= m_Player.GetSector() && m_iStartDrawSector - 242 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 205 <= m_Player.GetSector() && m_iStartDrawSector - 199 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 164 <= m_Player.GetSector() && m_iStartDrawSector - 156 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 123 <= m_Player.GetSector() && m_iStartDrawSector - 119 >= m_Player.GetSector()) ||

					(m_iStartDrawSector - 116 <= m_Player.GetSector() && m_iStartDrawSector - 113 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 82 <= m_Player.GetSector() && m_iStartDrawSector - 78 >= m_Player.GetSector()) ||
					(m_iStartDrawSector - 73 <= m_Player.GetSector() && m_iStartDrawSector - 70 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 41 <= m_Player.GetSector() && m_iStartDrawSector - 37 >= m_Player.GetSector()) ||
					(m_iStartDrawSector - 30 <= m_Player.GetSector() && m_iStartDrawSector - 27 >= m_Player.GetSector()) ||
				(m_iStartDrawSector - 0 <= m_Player.GetSector() && m_iStartDrawSector + 4 >= m_Player.GetSector()) ||
					(m_iStartDrawSector + 13 <= m_Player.GetSector() && m_iStartDrawSector + 16 >= m_Player.GetSector()) ||

				(m_iStartDrawSector + 56 <= m_Player.GetSector() && m_iStartDrawSector + 59 >= m_Player.GetSector()) ||
				(m_iStartDrawSector + 99 <= m_Player.GetSector() && m_iStartDrawSector + 102 >= m_Player.GetSector()) ||
				(m_iStartDrawSector + 142 <= m_Player.GetSector() && m_iStartDrawSector + 145 >= m_Player.GetSector())
*/

				g_Cursor.GetSector() - 6 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 35 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 76 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 75 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 32 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 11 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 54 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 97 == m_iStartDrawSector ||
				g_Cursor.GetSector() -140 == m_iStartDrawSector

				)
			{
				if((m_iStartDrawSector - (8 * MAPCOLUMNCOUNT)) / MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector - MAPCOLUMNCOUNT;
				}
			}
			MovePlayerUp();
		}
	}
	// here be the a_Sectors code... PUT IT IN ALREADY
}


//////////////////////////////////////////////////////
// HandleDownArrow()
//////////////////////////////////////////////////////
void CEngine::HandleDownArrow()
{
    if (m_bMonsterAttacking) return;
    if (IsShowingPlaque()) return;
    int iTargetSector = m_Player.GetSector() + MAPCOLUMNCOUNT;
    if (!m_bNoMonsters)
    {
        BOOL bFoughtMonster = CheckForAndHandleBattle();
        if (bFoughtMonster) return;
    }
    BOOL bHandledNPC = CheckForAndHandleNPC(iTargetSector);
    if (bHandledNPC) return;
    BOOL bHandledContainer = 
        CheckForAndHandleContainer(iTargetSector);
    if (bHandledContainer)
        return;
    int iDoorStatus = 
        CheckForAndHandleDoor(iTargetSector);
    //if (iDoorStatus == NODOOR || iDoorStatus == DOORUNLOCKED)
        
	if(g_Cursor.GetSector() / MAPCOLUMNCOUNT != 41)
	{
		if(m_Sectors[g_Cursor.GetSector() + MAPCOLUMNCOUNT] != 13)
		{
			if(	g_Cursor.GetSector() -182 == m_iStartDrawSector ||
				g_Cursor.GetSector() -223 == m_iStartDrawSector ||
				g_Cursor.GetSector() -264 == m_iStartDrawSector ||
				g_Cursor.GetSector() -263 == m_iStartDrawSector ||
				g_Cursor.GetSector() -220 == m_iStartDrawSector ||
				g_Cursor.GetSector() -177 == m_iStartDrawSector ||
				g_Cursor.GetSector() -134 == m_iStartDrawSector ||
				g_Cursor.GetSector() -91 == m_iStartDrawSector ||
				g_Cursor.GetSector() -48 == m_iStartDrawSector 
				)
			{
				if((m_iStartDrawSector  + (12 * MAPCOLUMNCOUNT)) / MAPCOLUMNCOUNT != 41)
				{
					m_iStartDrawSector = m_iStartDrawSector + MAPCOLUMNCOUNT;
				}
			}
			MovePlayerDown();
		}
	}
}

//////////////////////////////////////////////////////
// HandleLeftArrow()
//////////////////////////////////////////////////////
void CEngine::HandleLeftArrow()
{
    if (m_bMonsterAttacking) return;
    if (IsShowingPlaque()) return;
    int iTargetSector = m_Player.GetSector() - 1;
    if (!m_bNoMonsters)
    {
        BOOL bFoughtMonster = CheckForAndHandleBattle();
        if (bFoughtMonster) return;
    }
    BOOL bHandledNPC = CheckForAndHandleNPC(iTargetSector);
    if (bHandledNPC) return;
    BOOL bHandledContainer = 
        CheckForAndHandleContainer(iTargetSector);
    if (bHandledContainer)
        return;
    int iDoorStatus = 
        CheckForAndHandleDoor(iTargetSector);
    //if (iDoorStatus == NODOOR || iDoorStatus == DOORUNLOCKED)
        
	if(g_Cursor.GetSector() % MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector() - 1] != 13)
		{
			if	(
				g_Cursor.GetSector() - 6 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 35 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 76 == m_iStartDrawSector ||
				g_Cursor.GetSector() -263 == m_iStartDrawSector ||
				g_Cursor.GetSector() -220 == m_iStartDrawSector ||
				g_Cursor.GetSector() -177 == m_iStartDrawSector ||
				g_Cursor.GetSector() -134 == m_iStartDrawSector ||
				g_Cursor.GetSector() -91 == m_iStartDrawSector ||
				g_Cursor.GetSector() -48 == m_iStartDrawSector
				)
			{
				if(m_iStartDrawSector % MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector - 1;
				}
			}
			MovePlayerLeft();
		}
	}
}

//////////////////////////////////////////////////////
// HandleRightArrow()
//////////////////////////////////////////////////////
void CEngine::HandleRightArrow()
{
    if (m_bMonsterAttacking) return;
    if (IsShowingPlaque()) return;
    int iTargetSector = m_Player.GetSector() + 1;
    if (!m_bNoMonsters)
    {
        BOOL bFoughtMonster = CheckForAndHandleBattle();
        if (bFoughtMonster) return;
    }
    BOOL bHandledNPC = CheckForAndHandleNPC(iTargetSector);
    if (bHandledNPC) return;
    BOOL bHandledContainer = 
        CheckForAndHandleContainer(iTargetSector);
    if (bHandledContainer)
        return;
    int iDoorStatus = 
        CheckForAndHandleDoor(iTargetSector);
    //if (iDoorStatus == NODOOR || iDoorStatus == DOORUNLOCKED)
        
	if((g_Cursor.GetSector() + 1) % MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector() + 1] != 13)
		{
			if	(
				g_Cursor.GetSector() + 75 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 32 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 11 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 54 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 97 == m_iStartDrawSector ||
				g_Cursor.GetSector() -140 == m_iStartDrawSector ||
				g_Cursor.GetSector() -182 == m_iStartDrawSector ||
				g_Cursor.GetSector() -223 == m_iStartDrawSector ||
				g_Cursor.GetSector() -264 == m_iStartDrawSector
				)
			{
				if((m_iStartDrawSector + 21) % MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector + 1;
				}
			}
			MovePlayerRight();
		}
	}
}

//////////////////////////////////////////////////////
// HandleUpArrowBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleUpArrowBattleMenu()
{
	if(GetGameState() == FacingDecide)
	{
		m_Player.SetFacing(Up);
		m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + m_Player.GetFacing());
		return;
	}
	if(g_Cursor.GetSector() / MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector()-MAPCOLUMNCOUNT] != 13)
		{
			if	(
				g_Cursor.GetSector() - 6 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 35 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 76 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 75 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 32 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 11 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 54 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 97 == m_iStartDrawSector ||
				g_Cursor.GetSector() -140 == m_iStartDrawSector
				)
			{
				if((m_iStartDrawSector - (8 * MAPCOLUMNCOUNT)) / MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector - MAPCOLUMNCOUNT;
				}
			}
			g_Cursor.SetSector(g_Cursor.GetSector()-MAPCOLUMNCOUNT);
		}
	}
}

//////////////////////////////////////////////////////
// HandleDownArrowBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleDownArrowBattleMenu()
{
	if(GetGameState() == FacingDecide)
	{
		m_Player.SetFacing(Down);
		m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + m_Player.GetFacing());
		return;
	}
	if(g_Cursor.GetSector() / MAPCOLUMNCOUNT != 41)
	{
		if(m_Sectors[g_Cursor.GetSector() + MAPCOLUMNCOUNT] != 13)
		{
			if(	g_Cursor.GetSector() -182 == m_iStartDrawSector ||
				g_Cursor.GetSector() -223 == m_iStartDrawSector ||
				g_Cursor.GetSector() -264 == m_iStartDrawSector ||
				g_Cursor.GetSector() -263 == m_iStartDrawSector ||
				g_Cursor.GetSector() -220 == m_iStartDrawSector ||
				g_Cursor.GetSector() -177 == m_iStartDrawSector ||
				g_Cursor.GetSector() -134 == m_iStartDrawSector ||
				g_Cursor.GetSector() -91 == m_iStartDrawSector ||
				g_Cursor.GetSector() -48 == m_iStartDrawSector 
				)
			{
				if((m_iStartDrawSector  + (12 * MAPCOLUMNCOUNT)) / MAPCOLUMNCOUNT != 41)
				{
					m_iStartDrawSector = m_iStartDrawSector + MAPCOLUMNCOUNT;
				}
			}
			g_Cursor.SetSector((g_Cursor.GetSector() + MAPCOLUMNCOUNT));
		}
	}
}

//////////////////////////////////////////////////////
// HandleLeftArrowBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleLeftArrowBattleMenu()
{
	if(GetGameState() == FacingDecide)
	{
		m_Player.SetFacing(Left);
		m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + m_Player.GetFacing());
		return;
	}
	if(g_Cursor.GetSector() % MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector() - 1] != 13)
		{
			if(	g_Cursor.GetSector() - 6 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 35 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 76 == m_iStartDrawSector ||
				g_Cursor.GetSector() -263 == m_iStartDrawSector ||
				g_Cursor.GetSector() -220 == m_iStartDrawSector ||
				g_Cursor.GetSector() -177 == m_iStartDrawSector ||
				g_Cursor.GetSector() -134 == m_iStartDrawSector ||
				g_Cursor.GetSector() -91 == m_iStartDrawSector ||
				g_Cursor.GetSector() -48 == m_iStartDrawSector
				)
			{
				if(m_iStartDrawSector % MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector - 1;
				}
			}
			g_Cursor.SetSector(g_Cursor.GetSector() - 1);
		}
	}
}

//////////////////////////////////////////////////////
// HandleRightArrowBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleRightArrowBattleMenu()
{
	if(GetGameState() == FacingDecide)
	{
		m_Player.SetFacing(Right);
		m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + m_Player.GetFacing());
		return;
	}
	if((g_Cursor.GetSector() + 1) % MAPCOLUMNCOUNT != 0)
	{
		if(m_Sectors[g_Cursor.GetSector() + 1] != 13)
		{
			if(	g_Cursor.GetSector() + 75 == m_iStartDrawSector ||
				g_Cursor.GetSector() + 32 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 11 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 54 == m_iStartDrawSector ||
				g_Cursor.GetSector() - 97 == m_iStartDrawSector ||
				g_Cursor.GetSector() -140 == m_iStartDrawSector ||
				g_Cursor.GetSector() -182 == m_iStartDrawSector ||
				g_Cursor.GetSector() -223 == m_iStartDrawSector ||
				g_Cursor.GetSector() -264 == m_iStartDrawSector
				)
			{
				if((m_iStartDrawSector + 21) % MAPCOLUMNCOUNT != 0)
				{
					m_iStartDrawSector = m_iStartDrawSector + 1;
				}
			}
			g_Cursor.SetSector(g_Cursor.GetSector() + 1);
		}
	}
}

//////////////////////////////////////////////////////
// HandleEnter()
//////////////////////////////////////////////////////
void CEngine::HandleEnter()
{
	if(GetGameState() == PlayGame)
	{
		if(a_Sectors[g_Cursor.GetSector()] == 13 || a_Sectors[g_Cursor.GetSector()] == 20
			|| a_Sectors[g_Cursor.GetSector()] == 23
			|| a_Sectors[g_Cursor.GetSector()] == 24
			|| a_Sectors[g_Cursor.GetSector()] == 25)
		{
			return;
		}
		if(g_Cursor.GetSector() == m_Player.GetSector())
		{
			g_Cursor.SetPlayPTR(m_Player);
		}
		SetGameState(BattleMenu);
		TurnOnPlaque("M to move\nA to attack\nESC to cancel");
		return;
	}
	if(GetGameState() == AttackCursor || GetGameState() == AttackCursorDone)
	{
		if(GetGameState() == AttackCursor)
		{
			if(h_Sectors[g_Cursor.GetSector()] != 13)
			{
				for(int i = 0; i < MaxMonsters; i++)
				{
					if(a_Sectors[g_Cursor.GetSector()] != 13 && !mon[i].GetMonsterDead() && mon[i].GetSector() == g_Cursor.GetSector())
					{
						SetGameState(AttackDecide);
						TurnOnPlaque("Enter to Confirm\nESC to cancel");
						CurrentEnemy = i;
					}
				}
			}
		}
		else if (GetGameState() == AttackCursorDone)
		{
			if(h_Sectors[g_Cursor.GetSector()] != 13)
			{
				for(int i = 0; i < MaxMonsters; i++)
				{
					if(a_Sectors[g_Cursor.GetSector()] != 13 && !mon[i].GetMonsterDead() && mon[i].GetSector() == g_Cursor.GetSector())
					{
						SetGameState(AttackDecideDone);
						TurnOnPlaque("Enter to Confirm\nESC to cancel");
						CurrentEnemy = i;
					}
				}
				/*if(a_Sectors[g_Cursor.GetSector()] != 13)
				{
					SetGameState(AttackDecideDone);
					TurnOnPlaque("Enter to Confirm\nESC to cancel");
				}*/
			}
		}
		return;
	}
	if(GetGameState() == MoveCursor || GetGameState() == MoveCursorDone)
	{
		if(GetGameState() == MoveCursor)
		{
			if(h_Sectors[g_Cursor.GetSector()] != 13)
			{
				if(a_Sectors[g_Cursor.GetSector()] == 13)
				{
					SetGameState(MoveDecide);
					TurnOnPlaque("Enter to Confirm\nESC to cancel");
				}
			}
		}
		else if (GetGameState() == MoveCursorDone)
		{
			if(h_Sectors[g_Cursor.GetSector()] != 13)
			{
				if(a_Sectors[g_Cursor.GetSector()] == 13)
				{
					SetGameState(MoveDecideDone);
					TurnOnPlaque("Enter to Confirm\nESC to cancel");
				}
			}
		}
		return;
	}
	if(GetGameState() == AttackDecide || GetGameState() == AttackDecideDone)
	{
		TurnOnPlaque("DIE VILE DUMMY!!!\nTASTE MY NON-EXISTENT ATTACK\nANIMATION!!!");
		//later add code to check monster life

		mon[CurrentEnemy].SetMonsterDead(true);
		
		/*for(int i = 0; i < MaxMonsters; i++)
		{
			if()
			{
				
			}
		}*/
		

		if(GetGameState() == AttackDecide)
		{
			SetGameState(AttackRead);
		}
		else if(GetGameState() == AttackDecideDone)
		{
			SetGameState(AttackReadDone);
		}
		return;
	}
	if(GetGameState() == MoveDecide || GetGameState() == MoveDecideDone)
	{
		g_Cursor.GetPlayPTR()->SetTempSector(g_Cursor.GetPlayPTR()->GetSector());
		g_Cursor.GetPlayPTR()->SetSector(g_Cursor.GetSector());
		if(GetGameState() == MoveDecide)
		{
			TurnOnPlaque("A to attack\nS to Stay and End turn\nESC to cancel");
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			SetGameState(BattleMenuAttackOnly);
		}
		else if(GetGameState() == MoveDecideDone)
		{
			TurnOnPlaque("Set Facing:\n Adjust with Arrow Keys\nEnter to set");
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			SetGameState(FacingDecide);
		}
		return;
	}
	if(GetGameState() == AttackRead || GetGameState() == AttackReadDone)
	{
		TurnOffPlaque();

		if(GetGameState() == AttackRead)
		{
			TurnOnPlaque("M to move\nESC to cancel");
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			SetGameState(BattleMenuMoveOnly);
		}
		else if(GetGameState() == AttackReadDone)
		{
			TurnOnPlaque("Set Facing:\n Adjust with Arrow Keys\nEnter to set");
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			SetGameState(FacingDecide);
		}
		return;
	}
	if(GetGameState() == FacingDecide)
	{
		TurnOffPlaque();
		SetGameState(PlayGame);
		return;
	}
}

//////////////////////////////////////////////////////
// MovePlayerUp()
//////////////////////////////////////////////////////
void CEngine::MovePlayerUp()
{
	if (m_bAnimateMovement == 0)
	{
		m_bAnimateMovement = 1;
		g_Cursor.SetFacing(Up);
	}
}

//////////////////////////////////////////////////////
// MovePlayerDown()
//////////////////////////////////////////////////////
void CEngine::MovePlayerDown()
{
	if (m_bAnimateMovement == 0)
	{
		m_bAnimateMovement = 1;
		g_Cursor.SetFacing(Down);
		g_Cursor.SetSector((g_Cursor.GetSector() + MAPCOLUMNCOUNT));
	}
}

//////////////////////////////////////////////////////
// MovePlayerLeft()
//////////////////////////////////////////////////////
void CEngine::MovePlayerLeft()
{
	if (m_bAnimateMovement == 0)
	{
		m_bAnimateMovement = 1;
		g_Cursor.SetFacing(Left);

	}
}

//////////////////////////////////////////////////////
// MovePlayerRight()
//////////////////////////////////////////////////////
void CEngine::MovePlayerRight()
{
	if (m_bAnimateMovement == 0)
	{
		m_bAnimateMovement = 1;
		g_Cursor.SetFacing(Right);
		g_Cursor.SetSector(g_Cursor.GetSector() + 1);
	}
}

//////////////////////////////////////////////////////
// CharacterCanMove()
//////////////////////////////////////////////////////
BOOL CEngine::CharacterCanMove(int direction, int curSector)
{
    BOOL move = TRUE;
    if (direction == NORTH)
    {
        if (Sector2Row(curSector, MAPCOLUMNCOUNT) < 1) move = FALSE;
        if (PlayerBlocked(curSector, direction)) move = FALSE;
    }
    else if (direction == SOUTH)
    {
        if (Sector2Row(curSector, MAPCOLUMNCOUNT) > 40) move = FALSE;
        if (PlayerBlocked(curSector, direction)) move = FALSE;
    }
    else if (direction == EAST)
    {
        if (Sector2Column(curSector, MAPCOLUMNCOUNT) > 40) move = FALSE;
        if (PlayerBlocked(curSector, direction)) move = FALSE;
    }
    else if (direction == WEST)
    {
        if (Sector2Column(curSector, MAPCOLUMNCOUNT) < 1) move = FALSE;
        if (PlayerBlocked(curSector, direction)) move = FALSE;
    }
    return move;
}

//////////////////////////////////////////////////////
// PlayerBlocked()
//////////////////////////////////////////////////////
BOOL CEngine::PlayerBlocked(int iPlayerSector, int direction)
{
    BOOL blocked = FALSE;
    int iSector = iPlayerSector;
    if (direction == NORTH)
        iSector = iSector - MAPCOLUMNCOUNT;
    else if (direction == SOUTH)
        iSector = iSector + MAPCOLUMNCOUNT;
    else if (direction == EAST)
        iSector = iSector + 1;
    else if (direction == WEST)
        iSector = iSector - 1;
    int item = m_Sectors[iSector];
    switch (m_byMapType)
    {
        case TOWNEXTERIOR:
            if (item == BRICKWALL_EXT || item == VERTFENCE_EXT
                  || item == HORZFENCE_EXT || item == ANGLEFENCE_EXT
                  || item == TREE_EXT || item == WINDOW1_EXT
                  || item == WINDOW2_EXT || item == WELL_EXT
                  || item == FOUNTAIN_EXT || item == FOUNTAIN_EXT + 1
                  || item == STONEWALL_EXT
                  || (item >= WATER01_EXT && item <= WATER02_EXT))
                blocked = TRUE;
                break;
        case TOWNINTERIOR:
            if (item == BRICKWALL_INT || item == WINDOW1_INT
                || item == WINDOW2_INT || item == CUPBOARD_INT
                || item == TABLE01_INT || item == TABLE02_INT
                || item == TABLE03_INT 
                || item == BED01_INT || item == BED02_INT
                || item == BED03_INT || item == BED04_INT
                || item == FIREPLACE_INT || item == FIREPLACE_INT + 1
                || item == MANINCHAIR01_INT || item == MANINCHAIR01_INT + 1 
                || item == MANINCHAIR02_INT || item == MANINCHAIR02_INT + 1 
                || item == MANINCHAIR03_INT || item == MANINCHAIR03_INT + 1 
                || item == MANINCHAIR04_INT || item == MANINCHAIR04_INT + 1 
                || item == MANINBED01_INT || item == MANINBED01_INT + 1 
                || item == MANINBED02_INT || item == MANINBED02_INT + 1)
            blocked = TRUE;
            break;
        case WILDERNESS:
            if (item == MOUNTAIN01_WLD || item == MOUNTAIN02_WLD
                || item == MOUNTAIN03_WLD || item == MOUNTAIN04_WLD
                || item == WATER_WLD || item == WATER_WLD + 1
                || item == CASTLE01_WLD || item == CASTLE02_WLD
                || item == CASTLE03_WLD || item == CASTLE04_WLD
                || item == CASTLE05_WLD)
            blocked = TRUE;
            break;
        case DUNGEON:
            if (item == BRICKWALL_DUN || item == CUPBOARD_DUN
                || item == TABLE01_DUN || item == TABLE02_DUN
                || item == TABLE03_DUN 
                || item == WATER_DUN || item == WATER_DUN + 1 
                || item == BED01_DUN || item == BED02_DUN
                || item == BED03_DUN || item == BED04_DUN
                || item == FIREPLACE_DUN || item == FIREPLACE_DUN + 1
                || item == MANINCHAIR01_DUN || item == MANINCHAIR01_DUN + 1 
                || item == MANINCHAIR02_DUN || item == MANINCHAIR02_DUN + 1 
                || item == MANINCHAIR03_DUN || item == MANINCHAIR03_DUN + 1 
                || item == MANINCHAIR04_DUN || item == MANINCHAIR04_DUN + 1 
                || item == MANINBED01_DUN || item == MANINBED01_DUN + 1 
                || item == MANINBED02_DUN || item == MANINBED02_DUN + 1)
            blocked = TRUE;
            break;
    }

    return blocked;
}

//////////////////////////////////////////////////////
// StartAnimationTimer()
//////////////////////////////////////////////////////
void CEngine::StartAnimationTimer()
{
    SetTimer(m_hWnd, 1, 50, NULL);
}

//////////////////////////////////////////////////////
// HandleTimer()
//////////////////////////////////////////////////////
void CEngine::HandleTimer()
{
    if (m_bGamePaused) return;
    HandleMonsters();
    HandleFastestAnimation();
    ++m_iAnimationTimerCount;
    if (m_iAnimationTimerCount % 2 == 0)
    {
        HandleFastAnimation();
    }
    if (m_iAnimationTimerCount == 10)
    {
        m_iAnimationTimerCount = 0;
        HandleSlowAnimation();
    }
}

//////////////////////////////////////////////////////
// HandleSlowAnimation()
//////////////////////////////////////////////////////
void CEngine::HandleSlowAnimation()
{
    for (int x=0; x<MAPSECTORCOUNT; ++x)
    {
        if (m_Sectors[x] > 31 && !IsFastAnimationTile(m_Sectors[x]) &&
            !IsFastestAnimationTile(m_Sectors[x]))
        {
            if (m_bAnimationTilesUpdated)
                m_Sectors[x] = m_Sectors[x] - 1;
            else
                m_Sectors[x] = m_Sectors[x] + 1;
        }
    }
    for (int x=0; x < m_People.GetPersonCount(); ++x)
    {
        CPerson* pNPC = m_People.GetPerson(x);
        int r = rand() % 2;
	    if (r == 0)
        {
            int iTile = pNPC->GetTile();
            if (iTile == NPC01 || iTile == NPC02 || iTile == NPC03)
                pNPC->SetTile(iTile + 1);
            else
                pNPC->SetTile(iTile - 1);
        }
    }
    m_bAnimationTilesUpdated = !m_bAnimationTilesUpdated;
}

//////////////////////////////////////////////////////
// HandleFastAnimation()
//////////////////////////////////////////////////////
void CEngine::HandleFastAnimation()
{
	int c_ColumnRandom;
	int c_RowRandom;
	bool GoodPos = true;
	int SecPos;

   	switch(m_bFastAnimationTilesUpdated)
	{
		case 0:
			m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + (3 * m_Player.GetFacing()));
			
			for(int i = 0; i < MaxMonsters; i++)
			{
				if(mon[i].GetMonsterDead())
					mon[i].SetCurrentFrame(MYMONSTERDIEFRAME1);
			}

			break;

		case 2:
				for(int i = 0; i < MaxMonsters; i++)
				{
					if(mon[i].GetMonsterDead())
					{
						mon[i].SetCurrentFrame(MYMONSTERDIEFRAME3);
						mon[i].SetMonsterDead(false);
						mon[i].SetRespawn(true);
					}
				}
				m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + (3 * m_Player.GetFacing()));
				break;
		case 1:
				for(int i = 0; i < MaxMonsters; i++)
				{
					if(mon[i].GetMonsterDead())
						mon[i].SetCurrentFrame(MYMONSTERDIEFRAME2);
				}
				
				m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + (3 * m_Player.GetFacing()) + 1);
				break;
		case 3:
				
				for(int i = 0; i < MaxMonsters; i++)
				{

					if(mon[i].GetRespawn())
					{
						mon[i].SetRespawnCounter(mon[i].GetRespawnCounter() - 1);
						
						/*if(mon[CurrentEnemy].GetRespawnCounter() == 0)
						{
							mon[CurrentEnemy].SetRespawn(true);
						}*/
					}
				}

				for(int i = 0; i < MaxMonsters; i++)
				{
					if(mon[i].GetRespawn() && mon[i].GetRespawnCounter()==0)
					{
						c_ColumnRandom = rand() % 10;
						c_RowRandom = rand() % 6;

						do
						{
							// randomize monster sector?
							c_ColumnRandom = rand() % 10;
							c_RowRandom = rand() % 6;
							
							SecPos = 727 + c_ColumnRandom + (MAPCOLUMNCOUNT) * c_RowRandom;
							GoodPos = true;
							if(SecPos != m_Player.GetSector())
							{

								for(int j = 0; j < i; j++)
								{
									if(SecPos == mon[j].GetSector())
									{
										GoodPos = false;
									}
								}
							}
							else
							{
								GoodPos = false;
							}

							if(GoodPos)
								mon[i].SetSector(SecPos);

						}while(GoodPos == false);

						mon[i].SetCurrentFrame(MYMONSTERIDLEFRAME);
						//mon[CurrentEnemy].SetMonsterDead(false);
						mon[i].SetRespawn(false);
						mon[i].SetRespawnCounter(20);
					}
				}

				m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + (3 * m_Player.GetFacing()) + 2);
				break;
	}
	/*
            if (m_bFastAnimationTilesUpdated == 0)
                m_Player.SetCurrentFrame(13);
            else
			{
				m_Player.SetCurrentFrame(m_Player.GetHomeFrame() + (3 * m_Player.GetFacing()));
				//switch (m_Player.GetFacing())
				//{
				//case Up:
				//	m_Player.SetCurrentFrame(17);
				//	break;
				//case Right:
				//	m_Player.SetCurrentFrame(14);
				//	break;
				//case Down:
				//	m_Player.SetCurrentFrame(15);
				//	break;
				//case Left:
				//	m_Player.SetCurrentFrame(16);
				//	break;
				//}
			}
	*/
      //  }
   // }

	switch(m_bFastAnimationTilesUpdated)
	{
	case 0:
	case 1:
	case 2:
			m_bFastAnimationTilesUpdated++;
			break;
	case 3:
			m_bFastAnimationTilesUpdated = 0;
			break;
	}

}

//////////////////////////////////////////////////////
// HandleFastestAnimation()
//////////////////////////////////////////////////////
void CEngine::HandleFastestAnimation()
{
   switch(m_bAnimateMovement)
	{
				
		case 1:
				m_bAnimateMovement++;
				break;
		case 2:
				m_bAnimateMovement++;
				break;
		case 3:
				m_bAnimateMovement++;
				break;
		case 4:
				m_bAnimateMovement++;
				break;
		case 5:
			{
				m_bAnimateMovement = 0;

				switch (g_Cursor.GetFacing())
				{
					case Right:
						break;
					case Down:
						break;
					case Left:
						g_Cursor.SetSector(g_Cursor.GetSector() - 1);
						break;
					case Up:
						g_Cursor.SetSector((g_Cursor.GetSector() - MAPCOLUMNCOUNT));
						break;
				}
				
				
				break;
			}
	}
}

/////////////////////////////////////////////////////
//DrawMovingDude()
/////////////////////////////////////////////////////
void CEngine::DrawMovingDude(int DstCol, int DstRow, bool longrow)
{
		int PlayerMapCol = Sector2Column(g_Cursor.GetSector(), MAPCOLUMNCOUNT);
		int PlayerMapRow = Sector2Row(g_Cursor.GetSector(), MAPCOLUMNCOUNT);

		POINT DstPoint;

		

		switch (g_Cursor.GetFacing())
		{
		case Right:
			DstPoint.x = (Column2X(DstCol, DstRow, TILESIZE, MAPCOLUMNCOUNT) - 50 + (10 * m_bAnimateMovement));
			DstPoint.y = (Row2Y(DstRow, TILESIZE) - 25 + (5 * m_bAnimateMovement));
			break;
		case Down:
			DstPoint.x = (DudeColumn2X(DstCol, longrow, TILESIZE, MAPCOLUMNCOUNT) + 50 - (10 * m_bAnimateMovement));
			DstPoint.y = (Row2Y(DstRow, TILESIZE) - 25 + (5 * m_bAnimateMovement));
			break;
		case Left:
			DstPoint.x = (Column2X(DstCol, DstRow, TILESIZE, MAPCOLUMNCOUNT) - (10 * m_bAnimateMovement));
			DstPoint.y = (Row2Y(DstRow, TILESIZE) - (5 * m_bAnimateMovement));
			break;
		case Up:
			DstPoint.x = (Column2X(DstCol, DstRow, TILESIZE, MAPCOLUMNCOUNT) + (10 * m_bAnimateMovement));
			DstPoint.y = (Row2Y(DstRow, TILESIZE) - (5 * m_bAnimateMovement));
			break;
		}

		m_Direct3D.InitBlit();

		// Set up Blit parameters.		
		D3DXVECTOR2 centre(TILESIZE / 2, TILESIZE / 2);
		D3DXVECTOR2 scaling(1.0f, 1.0f);
		float angle = 0;
		D3DCOLOR colour = 0xFFFFFFFF;

		// Draw sprites.
		m_Direct3D.Blit(m_Direct3D.Getg_lpTextures(g_Cursor.GetTileType()), &DstPoint, &centre, &scaling, angle, colour);	

}
//////////////////////////////////////////////////////
// IsFastAnimationTile()
//////////////////////////////////////////////////////
BOOL CEngine::IsFastAnimationTile(int iTileNum)
{
    BOOL bFastAnimated = FALSE;
    if (m_byMapType == TOWNEXTERIOR)
    {
        switch (iTileNum)
        {
            case FOUNTAIN_EXT:
            case FOUNTAIN_EXT + 1:
            case LEFTTORCH:
            case LEFTTORCH + 1:
            case RIGHTTORCH:
            case RIGHTTORCH + 1:
                bFastAnimated = TRUE;
                break;
        }
    }
    else if (m_byMapType == TOWNINTERIOR)
    {
        switch (iTileNum)
        {
            case STAIRSUP_INT:
            case STAIRSUP_INT + 1:
            case STAIRSDOWN_INT:
            case STAIRSDOWN_INT + 1:
                bFastAnimated = TRUE;
                break;
        }
    }
    return bFastAnimated;
}

//////////////////////////////////////////////////////
// IsFastestAnimationTile()
//////////////////////////////////////////////////////
BOOL CEngine::IsFastestAnimationTile(int iTileNum)
{
    BOOL bFastestAnimated = FALSE;
    if (m_byMapType == TOWNEXTERIOR)
        {
        switch (iTileNum)
        {
            case STREETLIGHT_EXT:
            case STREETLIGHT_EXT + 1:
                bFastestAnimated = TRUE;
                break;
        }
    }
    else if (m_byMapType == TOWNINTERIOR)
        {
        switch (iTileNum)
        {
            case BRASIER_INT:
            case BRASIER_INT + 1:
            case STOVE_INT:
            case STOVE_INT + 1:
            case FIREPLACE_INT:
            case FIREPLACE_INT + 1:
                bFastestAnimated = TRUE;
                break;
        }
    }
    return bFastestAnimated;
}

//////////////////////////////////////////////////////
// ResetAnimation()
//////////////////////////////////////////////////////
void CEngine::ResetAnimation()
{
    m_iAnimationTimerCount = 0;
    m_bAnimationTilesUpdated = FALSE;
    m_bFastAnimationTilesUpdated = FALSE;
    m_bFastestAnimationTilesUpdated = FALSE;
}

//////////////////////////////////////////////////////
// IsShowingPlaque()
//////////////////////////////////////////////////////
BOOL CEngine::IsShowingPlaque()
{
    return m_bShowingPlaque;
}

//////////////////////////////////////////////////////
// PaintPlaque()
//////////////////////////////////////////////////////
void CEngine::PaintPlaque()
{
    unsigned char *vb_vertices;
    IDirect3DVertexBuffer8* pSquare;
    vertex m_square_vertices[] =
    {
        { 416.0f,  600.0f, 0.0f, 1.0f, 0.0f, 1.0f },  /* Lower left corner */
        { 416.0f,  444.0f,  0.0f, 1.0f, 0.0f, 0.0f }, /* Upper left corner */
        { 800.0f,  600.0f, 0.0f, 1.0f, 1.0f, 1.0f },  /* Lower right corner */
        { 800.0f,  444.0f,  0.0f, 1.0f, 1.0f, 0.0f }  /* Upper right corner */
    };

    // Create a font.
    LPD3DXFONT pFont = NULL;
	LOGFONT LogFont = {18, 0, 0, 0, FW_NORMAL, false, false, false,
        DEFAULT_CHARSET,OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
        PROOF_QUALITY, DEFAULT_PITCH, "Monotype Corsiva"};
    D3DXCreateFontIndirect(m_Direct3D.GetDevice(), &LogFont, &pFont);
    // Calculate the size of a rectangle that can hold the text.
    RECT r;
    r.left = 0;
    r.top = 0;
    r.right = 0;
    r.bottom = 0;
    pFont->DrawText(m_pstrPlaqueMsg, -1, &r, DT_CALCRECT, 0xffffffff);
    int iWidth = r.right - r.left;
    int iHeight = r.bottom - r.top;
    r.left = 444;//(800 - iWidth);
    r.right = 800;//r.left + iWidth;
    r.top = 486;//(600 - iHeight);
    r.bottom = 600;//r.top + iHeight;

    // Create and load the vertex buffer.
    HRESULT hResult = m_Direct3D.GetDevice()->
        CreateVertexBuffer(4*sizeof(vertex),D3DUSAGE_WRITEONLY,
        D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &pSquare);
    hResult = pSquare->Lock(0, 0, &vb_vertices, 0);
    memcpy(vb_vertices, m_square_vertices, sizeof(m_square_vertices));
    pSquare->Unlock();
    // Display the plaque texture.
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_SRCBLEND, 
        D3DBLEND_SRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_DESTBLEND, 
        D3DBLEND_INVSRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    if(SUCCEEDED(m_Direct3D.GetDevice()->BeginScene()))
    {
        m_Direct3D.GetDevice()->SetVertexShader(D3D8T_CUSTOMVERTEX);
        m_Direct3D.GetDevice()->SetStreamSource(0, pSquare, sizeof(vertex));
        m_Direct3D.GetDevice()->SetTexture(0, m_Direct3D.GetTexture());
        m_Direct3D.GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
        pFont->DrawText(m_pstrPlaqueMsg, -1, &r, DT_CENTER, 0xffffffff);
        m_Direct3D.GetDevice()->EndScene();
    }
    pSquare->Release();
    pFont->Release();
}

//////////////////////////////////////////////////////
// TurnOnPlaque()
//////////////////////////////////////////////////////
void CEngine::TurnOnPlaque(char* msg)
{
    strcpy(m_pstrPlaqueMsg, msg);
    m_bShowingPlaque = TRUE;

}

//////////////////////////////////////////////////////
// TurnOffPlaque()
//////////////////////////////////////////////////////
void CEngine::TurnOffPlaque()
{
    m_bShowingPlaque = FALSE;
}

//////////////////////////////////////////////////////
// CheckForAndHandleDoor()
//////////////////////////////////////////////////////
int CEngine::CheckForAndHandleDoor(int iSector)
{
    if (IsDoor(iSector))
    {
        BOOL bCouldOpenDoor = HandleDoor(iSector);
        if (bCouldOpenDoor)
        {
            m_Sound.PlaySound(ITEMOPEN);
            return DOORUNLOCKED;
        }
        else
            return DOORLOCKED;
    }
    return NODOOR;
}

//////////////////////////////////////////////////////
// IsDoor()
//////////////////////////////////////////////////////
BOOL CEngine::IsDoor(int iSector)
{
    if (m_Sectors[iSector] == DOOR_EXT && m_byMapType == TOWNEXTERIOR)
        return TRUE;
    else if (m_Sectors[iSector] == DOOR_INT && m_byMapType == TOWNINTERIOR)
        return TRUE;
    else if (m_Sectors[iSector] == DOOR_DUN && m_byMapType == DUNGEON)
        return TRUE;
    return FALSE;
}

//////////////////////////////////////////////////////
// HandleDoor()
//////////////////////////////////////////////////////
BOOL CEngine::HandleDoor(int iSector)
{
    BOOL bCouldEnterDoor = TRUE;
    int door = 0;
    CDoor* pDoor = FindDoor(iSector);
    if (pDoor->GetLocked() == TRUE)
    {
        if (m_Player.GetKeys() > 0)
        {
            m_Player.SetKeys(m_Player.GetKeys() - 1);
            pDoor->SetLocked(FALSE);
            TurnOnPlaque("You unlock the door.");
            bCouldEnterDoor = TRUE;
        }
        else
        {
            TurnOnPlaque("You need a key.");
            bCouldEnterDoor = FALSE;
        }
    }
    return bCouldEnterDoor;
}

//////////////////////////////////////////////////////
// FindDoor()
//////////////////////////////////////////////////////
CDoor* CEngine::FindDoor(int iSector)
{
    CDoor* pDoor;
    int iDoorNum = 0;
    BOOL bDoorFound = FALSE;
    while (!bDoorFound)
    {
        pDoor = m_Doors.GetDoor(iDoorNum);
        int iDoorSector = pDoor->GetSector();
        if (iDoorSector == iSector)
            bDoorFound = TRUE;
        else
            ++iDoorNum;
    }
    return pDoor;
}

//////////////////////////////////////////////////////
// CheckForAndHandleContainer()
//////////////////////////////////////////////////////
BOOL CEngine::CheckForAndHandleContainer(int iSector)
{
    BOOL bHandledContainer = FALSE;
    if (IsContainer(iSector))
    {
        HandleContainer(iSector);
        bHandledContainer = TRUE;
    }
    return bHandledContainer;
}

//////////////////////////////////////////////////////
// IsContainer()
//////////////////////////////////////////////////////
BOOL CEngine::IsContainer(int iSector)
{
    if (m_byMapType == TOWNINTERIOR)
    {
        if (m_Sectors[iSector] == CHEST_INT || 
              m_Sectors[iSector] == BARREL_INT || 
              m_Sectors[iSector] == FOOTLOCKER_INT)
            return TRUE;
    }
    else if (m_byMapType == DUNGEON)
    {
        if (m_Sectors[iSector] == CHEST_DUN || 
              m_Sectors[iSector] == BARREL_DUN || 
              m_Sectors[iSector] == FOOTLOCKER_DUN)
            return TRUE;
    }
    return FALSE;
}

//////////////////////////////////////////////////////
// HandleContainer()
//////////////////////////////////////////////////////
BOOL CEngine::HandleContainer(int iSector)
{
    BOOL bCouldOpenContainer = TRUE;
    CContainer* pContainer = FindContainer(iSector);
    if (pContainer->GetLocked() == TRUE)
    {
        if (m_Player.GetKeys() > 0)
        {
            m_Player.SetKeys(m_Player.GetKeys() - 1 );
            pContainer->SetLocked(FALSE);
            if (ContainerEmpty(pContainer))
                TurnOnPlaque("You unlock it. It's empty.");
            else
                RetrieveItemsFromContainer(pContainer, "You unlock it.");
            bCouldOpenContainer = TRUE;
        }
        else
        {
            TurnOnPlaque("You need a key.");
            bCouldOpenContainer = FALSE;
        }
    }
    else
    {
        if (ContainerEmpty(pContainer))
            TurnOnPlaque("It's empty.");
        else
            RetrieveItemsFromContainer(pContainer, "You open it.");
        bCouldOpenContainer = TRUE;
    }

    return bCouldOpenContainer;
}

//////////////////////////////////////////////////////
// FindContainer()
//////////////////////////////////////////////////////
CContainer* CEngine::FindContainer(int iSector)
{
    CContainer* pContainer;
    int iContainer = 0;
    BOOL bContainerFound = FALSE;
    while (!bContainerFound)
    {
        pContainer = m_Containers.GetContainer(iContainer);
        int iContainerSector = pContainer->GetSector();
        if (iContainerSector == iSector)
            bContainerFound = TRUE;
        else
            ++iContainer;
    }
    return pContainer;
}

//////////////////////////////////////////////////////
// ContainerEmpty()
//////////////////////////////////////////////////////
BOOL CEngine::ContainerEmpty(CContainer* pContainer)
{
    if (pContainer->GetArmor() == NOARMOR &&
            pContainer->GetWeapon() == NOWEAPON &&
            pContainer->GetGold() == NOGOLD &&
            pContainer->GetKeys() == NOKEYS &&
            pContainer->GetPotion() == NOPOTION)
        return TRUE;
    return FALSE;
}

//////////////////////////////////////////////////////
// RetrieveItemsFromContainer()
//////////////////////////////////////////////////////
void CEngine::RetrieveItemsFromContainer(CContainer* pContainer, char* msg)
{
    char str[1024];
    strcpy(str, msg);
    RetrieveGold(pContainer, str);
    RetrieveKeys(pContainer, str);
    RetrievePotion(pContainer, str);
    RetrieveWeapon(pContainer, str);
    RetrieveArmor(pContainer, str);
    TurnOnPlaque(str);
}

//////////////////////////////////////////////////////
// RetrieveGold()
//////////////////////////////////////////////////////
void CEngine::RetrieveGold(CContainer* pContainer, char* msg)
{
    if (pContainer->GetGold() > 0)
    {
        m_Player.SetGold(m_Player.GetGold() + 
            pContainer->GetGold());
        wsprintf(&msg[strlen(msg)], "\nYou find %d gold.", 
            pContainer->GetGold());
        pContainer->SetGold(0);
    }
}

//////////////////////////////////////////////////////
// RetrieveKeys()
//////////////////////////////////////////////////////
void CEngine::RetrieveKeys(CContainer* pContainer, char* msg)
{
    if (pContainer->GetKeys() > 0)
    {
        int iNumKeys = pContainer->GetKeys();
        m_Player.SetKeys(m_Player.GetKeys() + iNumKeys);
        if (iNumKeys = 1)
            wsprintf(&msg[strlen(msg)], "\nYou find %d key.", iNumKeys);
        else
            wsprintf(&msg[strlen(msg)], "\nYou find %d keys.", iNumKeys);
        pContainer->SetKeys(0);
    }
}

//////////////////////////////////////////////////////
// RetrievePotion()
//////////////////////////////////////////////////////
void CEngine::RetrievePotion(CContainer* pContainer, char* msg)
{
    if (pContainer->GetPotion() > 0)
    {
        int iNumPotions = pContainer->GetPotion();
        m_Player.SetPotions(m_Player.GetPotions() + iNumPotions);
        if (iNumPotions = 1)
            wsprintf(&msg[strlen(msg)], "\nYou find %d potion.", iNumPotions);
        else
            wsprintf(&msg[strlen(msg)], "\nYou find %d potions.", iNumPotions);
        pContainer->SetPotion(0);
    }
}

//////////////////////////////////////////////////////
// RetrieveWeapon()
//////////////////////////////////////////////////////
void CEngine::RetrieveWeapon(CContainer* pContainer, char* msg)
{
    int iWeaponType = pContainer->GetWeapon();
    if (iWeaponType != NOWEAPON)
    {
        wsprintf(&msg[strlen(msg)], "\nYou find a level %d weapon.",
            iWeaponType);
        if (iWeaponType > m_Player.GetWeapon())
        {
            m_Player.SetWeapon(iWeaponType);
            strcpy(&msg[strlen(msg)], "\nWEAPON EQUIPPED.");
        }
        else
            strcpy(&msg[strlen(msg)], "\nCAN'T USE WEAPON.");
       pContainer->SetWeapon(NOWEAPON);
    }
}

//////////////////////////////////////////////////////
// RetrieveArmor()
//////////////////////////////////////////////////////
void CEngine::RetrieveArmor(CContainer* pContainer, char* msg)
{
    int iArmorType = pContainer->GetArmor();
    if (iArmorType != NOARMOR)
    {
        wsprintf(&msg[strlen(msg)], "\nYou find level %d armor.",
            iArmorType);
        if (iArmorType > m_Player.GetArmor())
        {
            m_Player.SetArmor(iArmorType);
            strcpy(&msg[strlen(msg)], "\nARMOR EQUIPPED.");
        }
        else
            strcpy(&msg[strlen(msg)], "\nCAN'T USE ARMOR.");
        pContainer->SetArmor(NOARMOR);
    }
}

//////////////////////////////////////////////////////
// ShowInventory()
//////////////////////////////////////////////////////
void CEngine::ShowInventory()
{
    if (m_bMonsterAttacking || m_bAskingIfLoad || m_bAskingIfSave || 
        m_bAskingIfQuit || m_bPlayerDead) return;
    char pstrMsg[256];
    wsprintf(pstrMsg, "Gold: %d\nKeys: %d\nPotions: %d\n\
Level %d Weapon\nLevel %d Armor",
        m_Player.GetGold(), m_Player.GetKeys(), 
        m_Player.GetPotions(), m_Player.GetWeapon(),
        m_Player.GetArmor());
    TurnOnPlaque(pstrMsg);
}

//////////////////////////////////////////////////////
// CheckForSecretDoor()
//////////////////////////////////////////////////////
int CEngine::CheckForSecretDoor(int TileNumber, int iSector)
{
    int iFinalTile = TileNumber;
    CDoor* pDoor = FindDoor(iSector);
    if (pDoor->GetSecret())
    {
        if (TileNumber == DOOR_INT && m_byMapType == TOWNINTERIOR)
            iFinalTile = BRICKWALL_INT;
        else if (TileNumber == DOOR_EXT && m_byMapType == TOWNEXTERIOR)
            iFinalTile = BRICKWALL_EXT;
        else if (TileNumber == DOOR_DUN && m_byMapType == DUNGEON)
            iFinalTile = BRICKWALL_DUN;
    }
    return iFinalTile;
}

//////////////////////////////////////////////////////
// SectorHasPerson()
//////////////////////////////////////////////////////
BOOL CEngine::SectorHasPerson(int iSector, int& person)
{
    for (int i=0; i<m_People.GetPersonCount(); ++i)
    {
        if (m_People.GetPerson(i)->GetSector() == iSector)
        {
            person = i;
            return TRUE;
        }
    }
    return FALSE;
}

//////////////////////////////////////////////////////
// MoveNPCs()
//////////////////////////////////////////////////////
void CEngine::MoveNPCs()
{
    static time_t oldTime = time(NULL);
    time_t newTime = time(NULL);
    if (newTime < oldTime+1) return;
    oldTime = newTime;

    for (int person=0; person<m_People.GetPersonCount(); ++person)
    {
        if (m_People.GetPerson(person)->GetCanMove() == TRUE)
        {
            int r = rand() % 2;
            if (r == 0)
            {
                r = rand() % 4;
                switch(r)
                {
                case 0:
                    MoveNPCNorth(person);
                    break;
                case 1:
                    MoveNPCEast(person);
                    break;
                case 2:
                    MoveNPCSouth(person);
                    break;
                case 3:
                    MoveNPCWest(person);
                }
            }
        }
    }
}

//////////////////////////////////////////////////////
// MoveNPCNorth()
//////////////////////////////////////////////////////
void CEngine::MoveNPCNorth(int person)
{
    int iSector = m_People.GetPerson(person)->GetSector() - MAPCOLUMNCOUNT;
    if (m_Sectors[iSector] == DOOR_EXT || 
        m_Sectors[iSector] == DOOR_INT || 
        m_Sectors[iSector] == DOOR_DUN)
        return;

    BOOL canMove = CharacterCanMove(NORTH, 
        m_People.GetPerson(person)->GetSector());
    if (canMove && !IsShowingPlaque())
        m_People.GetPerson(person)->SetSector(iSector);
}

//////////////////////////////////////////////////////
// MoveNPCEast()
//////////////////////////////////////////////////////
void CEngine::MoveNPCEast(int person)
{
    int iSector = m_People.GetPerson(person)->GetSector() + 1;
    if (m_Sectors[iSector] == DOOR_EXT || 
        m_Sectors[iSector] == DOOR_INT || 
        m_Sectors[iSector] == DOOR_DUN)
        return;

    BOOL canMove = CharacterCanMove(EAST, 
        m_People.GetPerson(person)->GetSector());
    if (canMove && !IsShowingPlaque())
        m_People.GetPerson(person)->SetSector(iSector);
}

//////////////////////////////////////////////////////
// MoveNPCSouth()
//////////////////////////////////////////////////////
void CEngine::MoveNPCSouth(int person)
{
    int iSector = m_People.GetPerson(person)->GetSector() + MAPCOLUMNCOUNT;
    if (m_Sectors[iSector] == DOOR_EXT || 
        m_Sectors[iSector] == DOOR_INT || 
        m_Sectors[iSector] == DOOR_DUN)
        return;

    BOOL canMove = CharacterCanMove(SOUTH, 
        m_People.GetPerson(person)->GetSector());
    if (canMove && !IsShowingPlaque())
        m_People.GetPerson(person)->SetSector(iSector);
}

//////////////////////////////////////////////////////
// MoveNPCWest()
//////////////////////////////////////////////////////
void CEngine::MoveNPCWest(int person)
{
    int iSector = m_People.GetPerson(person)->GetSector() - 1;
    if (m_Sectors[iSector] == DOOR_EXT || 
        m_Sectors[iSector] == DOOR_INT || 
        m_Sectors[iSector] == DOOR_DUN)
        return;

    BOOL canMove = CharacterCanMove(WEST, 
        m_People.GetPerson(person)->GetSector());
    if (canMove && !IsShowingPlaque())
        m_People.GetPerson(person)->SetSector(iSector);
}

//////////////////////////////////////////////////////
// CheckForAndHandleNPC()
//////////////////////////////////////////////////////
BOOL CEngine::CheckForAndHandleNPC(int iSector)
{
    BOOL bHandledNPC = FALSE;
    int person;
    if (SectorHasPerson(iSector, person))
    {
        HandleNPC(person);
        bHandledNPC = TRUE;
    }
    return bHandledNPC;
}

//////////////////////////////////////////////////////
// HandleNPC()
//////////////////////////////////////////////////////
void CEngine::HandleNPC(int iNPCNum)
{
    CPerson* pNPC = m_People.GetPerson(iNPCNum);
    char msg[128];
    char name[128];
    strcpy(name, m_People.GetPerson(iNPCNum)->GetName());
    strcpy(name, &name[1]);
    name[strlen(name) - 1] = 0;
    wsprintf(msg, "Hi! I'm %s.", name);
    TurnOnPlaque(msg);
}

//////////////////////////////////////////////////////
// CheckForAndHandleBattle()
//////////////////////////////////////////////////////
BOOL CEngine::CheckForAndHandleBattle()
{
    if (IsBattleLocation())
    {
        int r = rand() % 10;
        if (r == 0)
        {
			m_pCurrentMonster = GetBattleMap();
			//m_bMonsterAttacking = TRUE;
			//m_bPlayerTurnToAttack = TRUE;
            return TRUE;
        }
    }
    return FALSE;
}

//////////////////////////////////////////////////////
// PaintBattlePlaque()
//////////////////////////////////////////////////////
void CEngine::PaintBattlePlaque()
{
    unsigned char *vb_vertices;
    IDirect3DVertexBuffer8* pSquare;
    vertex m_square_vertices[] =
    {
        { 416.0f,  600.0f, 0.0f, 1.0f, 0.0f, 1.0f },  /* Lower left corner */
        { 416.0f,  344.0f,  0.0f, 1.0f, 0.0f, 0.0f }, /* Upper left corner */
        { 800.0f,  600.0f, 0.0f, 1.0f, 1.0f, 1.0f },  /* Lower right corner */
        { 544.0f,  344.0f,  0.0f, 1.0f, 1.0f, 0.0f }  /* Upper right corner */
    };

    // Create a font.
    LPD3DXFONT pFont = NULL;
    LOGFONT LogFont = {16, 0, 0, 0, FW_NORMAL, false, false, false,
        DEFAULT_CHARSET,OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
        PROOF_QUALITY, DEFAULT_PITCH, "Times New Roman"};
    D3DXCreateFontIndirect(m_Direct3D.GetDevice(), &LogFont, &pFont);

    char msg[1024];
    wsprintf(msg, "A %s attacks!\n", m_pCurrentMonster->GetName());
    wsprintf(&msg[strlen(msg)], "Monster Hit Points = %d\n", 
        m_pCurrentMonster->GetRemainingHitPoints());
    if (m_bPlayerTurnToAttack)
        strcpy(&msg[strlen(msg)], "A = Attack\nP = Take Potion\nR = Run");
    else
        strcpy(&msg[strlen(msg)], "The creature prepares to attack");

    wsprintf(&msg[strlen(msg)], "\nHit Points = %d", m_Player.GetHitPoints());

    // Calculate the size of a rectangle that can hold the text.
    RECT r;
    r.left = 0;
    r.top = 0;
    r.right = 0;
    r.bottom = 0;
    pFont->DrawText(msg, -1, &r, DT_CALCRECT, 0xff000000);
    int iWidth = r.right - r.left;
    int iHeight = r.bottom - r.top;
    r.left = (640 - iWidth) / 2;
    r.right = r.left + iWidth;
    r.top = 310;
    r.bottom = r.top + iHeight;

    // Create and load the vertex buffer.
    HRESULT hResult = m_Direct3D.GetDevice()->
        CreateVertexBuffer(4*sizeof(vertex),D3DUSAGE_WRITEONLY,
        D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &pSquare);
    hResult = pSquare->Lock(0, 0, &vb_vertices, 0);
    memcpy(vb_vertices, m_square_vertices, sizeof(m_square_vertices));
    pSquare->Unlock();

    // Display the plaque texture.
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    m_Direct3D.GetDevice()->SetTextureStageState(0, 
        D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_SRCBLEND, 
        D3DBLEND_SRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_DESTBLEND, 
        D3DBLEND_INVSRCALPHA);
    m_Direct3D.GetDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    if(SUCCEEDED(m_Direct3D.GetDevice()->BeginScene()))
    {
        m_Direct3D.GetDevice()->SetVertexShader(D3D8T_CUSTOMVERTEX);
        m_Direct3D.GetDevice()->SetStreamSource(0, pSquare, sizeof(vertex));
        m_Direct3D.GetDevice()->SetTexture(0, m_Direct3D.GetTexture());
        m_Direct3D.GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
        pFont->DrawText(msg, -1, &r, DT_CENTER, 0xff000000);
        m_Direct3D.GetDevice()->EndScene();
    }
    pSquare->Release();
    pFont->Release();
}

//////////////////////////////////////////////////////
// AttackMonster()
//////////////////////////////////////////////////////
void CEngine::AttackMonster()
{
    if (m_bPlayerTurnToAttack && m_iCombatDelayCounter == 0)
    {
        m_Sound.PlaySound(MONSTERHIT);
        m_iMonsterDamage = (rand() % 10) + 2;
        m_bPlayerTurnToAttack = FALSE;
    }
}

//////////////////////////////////////////////////////
// HandleMonsters()
//////////////////////////////////////////////////////
void CEngine::HandleMonsters()
{
    if (!m_bMonsterAttacking) return;
    if (!CombatDelayOver()) return;

    if (m_bPlayerTurnToAttack)
        AnimateIdleMonster();
    else if (m_iMonsterDamage)
        AnimateMonsterDamage();
    else if (m_bRunningFromMonster)
        AttackRunningPlayer();
    else if (!m_bPlayerTurnToAttack)
        AttackPlayer();
}

//////////////////////////////////////////////////////
// CombatDelayOver()
//////////////////////////////////////////////////////
BOOL CEngine::CombatDelayOver()
{
    if (m_iCombatDelayCounter)
    {
        --m_iCombatDelayCounter;
        if (m_iCombatDelayCounter == 0)
        {
            if (m_bRunningFromMonster)
            {
                m_bRunningFromMonster = FALSE;
                m_bMonsterAttacking = FALSE;
            }
            m_iCurrentMonsterFrame = MONSTERIDLEFRAME1;
            return TRUE;
        }
        return FALSE;
    }
    return TRUE;
}

//////////////////////////////////////////////////////
// AnimateIdleMonster()
//////////////////////////////////////////////////////
void CEngine::AnimateIdleMonster()
{
    int r = rand() % 5;
    if (r == 0)
    {
        if (m_iCurrentMonsterFrame != MONSTERIDLEFRAME2)
            m_iCurrentMonsterFrame = MONSTERIDLEFRAME2;
        else
            m_iCurrentMonsterFrame = MONSTERIDLEFRAME1;
    }
}

//////////////////////////////////////////////////////
// AnimateMonsterDamage()
//////////////////////////////////////////////////////
void CEngine::AnimateMonsterDamage()
{
    m_iCurrentMonsterFrame = MONSTERHITFRAME;
    --m_iMonsterDamage;
    if (m_iMonsterDamage == 0)
    {
        m_iCombatDelayCounter = 15;
        m_iCurrentMonsterFrame = MONSTERIDLEFRAME1;
    }
    int iRemainingHitPoints = m_pCurrentMonster->GetRemainingHitPoints();
    iRemainingHitPoints -= (m_Player.GetExperience() / 100) + 1;
    m_pCurrentMonster->SetRemainingHitPoints(iRemainingHitPoints);
    if (m_pCurrentMonster->GetRemainingHitPoints() < 1)
    {
        m_Sound.PlaySound(MONSTERDIES);
        m_bMonsterAttacking = FALSE;
        m_iCurrentMonsterFrame = 0;
        m_Player.SetExperience(m_Player.GetExperience() + 
            m_pCurrentMonster->GetExperienceValue());
        int iGold = rand() % m_pCurrentMonster->GetMaxGold();
        m_Player.SetGold(m_Player.GetGold() + iGold); 
        m_Player.SetMaxHitPoints((m_Player.GetExperience()/100)*5+10);
        char msg[80];
        wsprintf(msg, "You defeat the creature and \n\
get %d gold and %d experience.", 
            iGold, m_pCurrentMonster->GetExperienceValue());
        TurnOnPlaque(msg);
    }
}

//////////////////////////////////////////////////////
// AttackRunningPlayer()
//////////////////////////////////////////////////////
void CEngine::AttackRunningPlayer()
{
    m_iCurrentMonsterFrame = MONSTERATTACKFRAME;
    int iDamage = rand() % m_pCurrentMonster->GetMaxAttackDamage();
    iDamage -= m_Player.GetArmor();
    if (iDamage < 0) iDamage = 0;
    if (iDamage > 0)
        m_Sound.PlaySound(PLAYERHIT);
    m_Player.SetHitPoints(m_Player.GetHitPoints() - iDamage);
    if (m_Player.GetHitPoints() <= 0)
    {
        m_bMonsterAttacking = FALSE;
        EndGame();
    }
    m_iCombatDelayCounter = 15;
}

//////////////////////////////////////////////////////
// AttackPlayer()
//////////////////////////////////////////////////////
void CEngine::AttackPlayer()
{
    m_iCurrentMonsterFrame = MONSTERATTACKFRAME;
    int iDamage = rand() % m_pCurrentMonster->GetMaxAttackDamage();
    iDamage -= m_Player.GetArmor();
    if (iDamage < 0) iDamage = 0;
    if (iDamage > 0)
        m_Sound.PlaySound(PLAYERHIT);
    m_Player.SetHitPoints(m_Player.GetHitPoints() - iDamage);
    if (m_Player.GetHitPoints() <= 0)
    {
        m_bMonsterAttacking = FALSE;
        EndGame();
    }
   m_bPlayerTurnToAttack = TRUE;
    m_iCombatDelayCounter = 15;
}

//////////////////////////////////////////////////////
// TakePotion()
//////////////////////////////////////////////////////
void CEngine::TakePotion()
{
    if (!m_bPlayerTurnToAttack) return;
    if (m_Player.GetPotions() > 0)
    {
        m_Player.SetPotions(m_Player.GetPotions() - 1);
        int iHealingPoints = ((m_Player.GetExperience() / 100) + 1) * 5;
        m_Player.SetHitPoints(m_Player.GetHitPoints() + iHealingPoints);
        if (m_Player.GetHitPoints() > m_Player.GetMaxHitPoints())
            m_Player.SetHitPoints(m_Player.GetMaxHitPoints());
        m_bPlayerTurnToAttack = FALSE;
    }
}

//////////////////////////////////////////////////////
// RunFromMonster()
//////////////////////////////////////////////////////
void CEngine::RunFromMonster()
{
    m_bRunningFromMonster = TRUE;
    m_bPlayerTurnToAttack = FALSE;
}

//////////////////////////////////////////////////////
// SaveMapFile()
//////////////////////////////////////////////////////
void CEngine::SaveMapFile(BOOL bFullSave)
{
    ResetMap();
    ResetAnimation();
    char fileName[MAX_PATH];
    wsprintf(fileName, "Temp\\%s", m_pstrCurrentMapFile);
	std::ofstream mapFile(fileName, std::ios::binary);
    mapFile.write((char*)&m_byMapType, 1);
    mapFile.write(m_Sectors, sizeof m_Sectors);
    mapFile.close();
    wsprintf(fileName, "Temp\\%s.peo", m_pstrCurrentMapFile);
    SavePeopleFile(fileName);
    wsprintf(fileName, "Temp\\%s.itm", m_pstrCurrentMapFile);
    SaveContainerFile(fileName);
    wsprintf(fileName, "Temp\\%s.dor", m_pstrCurrentMapFile);
    SaveDoorFile(fileName);

    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
    //if (bFullSave)
    //{
    //    char oldFileName[MAX_PATH];
    //    char newFileName[MAX_PATH];
    //    WIN32_FIND_DATA fileData;
    //    HANDLE fHandle = FindFirstFile("Temp\\*.*", &fileData);
    //    wsprintf(newFileName, "Save\\%s", fileData.cFileName);
    //    wsprintf(oldFileName, "Temp\\%s", fileData.cFileName);
    //    CopyFile(oldFileName, newFileName, FALSE);
    //    while(FindNextFile(fHandle, &fileData))
    //    {
    //        wsprintf(newFileName, "Save\\%s", fileData.cFileName);
    //        wsprintf(oldFileName, "Temp\\%s", fileData.cFileName);
    //        CopyFile(oldFileName, newFileName, FALSE);
    //    }
    //    FindClose(fHandle);
    //}
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
}

//////////////////////////////////////////////////////
// SavePeopleFile()
//////////////////////////////////////////////////////
void CEngine::SavePeopleFile(char* pstrFileName)
{
    std::ofstream m_peopleFile(pstrFileName);
    m_peopleFile << m_People.GetPersonCount() << '\n';

    for (int person=0; person<m_People.GetPersonCount(); ++person)
    {
        CPerson* pPerson = m_People.GetPerson(person);
        m_peopleFile << pPerson->GetName() << '\n';
        m_peopleFile << pPerson->GetSector() << '\n';
        if (pPerson->GetCanMove())
            m_peopleFile << "#TRUE#\n";
        else
            m_peopleFile << "#FALSE#\n";
        m_peopleFile << pPerson->GetTile() << '\n';
    }
    m_peopleFile.close();
}

//////////////////////////////////////////////////////
// SaveContainerFile()
//////////////////////////////////////////////////////
void CEngine::SaveContainerFile(char* fileName)
{
    std::ofstream ContainerFile(fileName);
    int iCount = m_Containers.GetContainerCount();
    ContainerFile << iCount << '\n';

    for (int container=0; container < iCount; ++container)
    {
        CContainer* pContainer = m_Containers.GetContainer(container);
        ContainerFile << pContainer->GetGold() << '\n';
        ContainerFile << pContainer->GetKeys() << '\n';
        ContainerFile << pContainer->GetPotion() << '\n';
        ContainerFile << pContainer->GetArmor() << '\n';
        ContainerFile << pContainer->GetWeapon() << '\n';
        if (pContainer->GetLocked())
            ContainerFile << "#TRUE#\n";
        else
            ContainerFile << "#FALSE#\n";
        ContainerFile << pContainer->GetSector() << '\n';
        ContainerFile << pContainer->GetTile() << '\n';
    }
    ContainerFile.close();
}

//////////////////////////////////////////////////////
// SaveDoorFile()
//////////////////////////////////////////////////////
void CEngine::SaveDoorFile(char* pstrFileName)
{
    std::ofstream DoorFile(pstrFileName);
    int iCount = m_Doors.GetDoorCount();
    DoorFile << iCount << '\n';

    for (int door=0; door < iCount; ++door)
    {
        CDoor* pDoor = m_Doors.GetDoor(door);
        if (pDoor->GetSecret())
            DoorFile << "#TRUE#\n";
        else
            DoorFile << "#FALSE#\n";
        if (pDoor->GetLocked())
            DoorFile << "#TRUE#\n";
        else
            DoorFile << "#FALSE#\n";
        DoorFile << pDoor->GetSector() << '\n';
        DoorFile << pDoor->GetTile() << '\n';
    }
    DoorFile.close();
}

//////////////////////////////////////////////////////
// ResetMap()
//////////////////////////////////////////////////////
void CEngine::ResetMap()
{
    for (int x=0; x<MAPSECTORCOUNT; ++x)
    {
        if (m_Sectors[x] > 31)
            m_Sectors[x] -= m_Sectors[x] % 2;
    }
}

//////////////////////////////////////////////////////
// HandleS()
//////////////////////////////////////////////////////
void CEngine::HandleS()
{
    if (m_bMonsterAttacking || m_bAskingIfLoad || m_bAskingIfSave || 
        m_bAskingIfQuit || m_bPlayerDead) return;
    TurnOnPlaque(
"The new save files will\n\
overwrite your previous ones.\n\n\
Are you sure you want\n\
to save the game? (Y/N)");
    m_bAskingIfSave = TRUE;
}

//////////////////////////////////////////////////////
// HandleL()
//////////////////////////////////////////////////////
void CEngine::HandleL()
{
    if (m_bMonsterAttacking || m_bAskingIfLoad || m_bAskingIfSave || 
        m_bAskingIfQuit || m_bPlayerDead) return;
    TurnOnPlaque(
"Are you sure you want\n\
to load the previously\n\
saved game? (Y/N)");
    m_bAskingIfLoad = TRUE;
}

//////////////////////////////////////////////////////
// HandleSpace()
//////////////////////////////////////////////////////
void CEngine::HandleSpace()
{
    if (m_bPlayerDead)
        PostQuitMessage(WM_QUIT);
    if (IsShowingPlaque() && !m_bAskingIfSave && !m_bAskingIfLoad
            && !m_bAskingIfQuit)
        TurnOffPlaque();
}

//////////////////////////////////////////////////////
// HandleEscapeBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleEscapeBattleMenu()
{
	if(GetGameState() == BattleMenu)
	{
		if (IsShowingPlaque() && !m_bAskingIfSave && !m_bAskingIfLoad
           && !m_bAskingIfQuit)
		{
			TurnOffPlaque();
		}
		SetGameState(PlayGame);
		return;
	}
	if(GetGameState() == BattleMenuAttackOnly /*|| GetGameState() == BattleMenuMoveOnly*/)
	{
		TurnOffPlaque();
        if(GetGameState() == BattleMenuAttackOnly)
		{
			g_Cursor.GetPlayPTR()->SetSector(g_Cursor.GetPlayPTR()->GetTempSector());
			SetGameState(MoveCursor);
			move_highlights();
		}
		//else if(GetGameState() == BattleMenuMoveOnly)
		//{
		//	SetGameState(AttackCursor);
		//}
		return;
	}
	if(GetGameState() == AttackCursor || GetGameState() == AttackCursorDone)
	{
/*		
		for(int CaiCount = 0; CaiCount <1764; CaiCount++)
		{
			h_Sectors[CaiCount] = 13;
		}
*/
		g_Cursor.SetSector(g_Cursor.GetPlayPTR()->GetSector());
		if(GetGameState() == AttackCursor)
		{
			SetGameState(BattleMenu);
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			TurnOnPlaque("M to move\nA to attack\nESC to cancel");
		}
		else if (GetGameState() == AttackCursorDone)
		{
			SetGameState(BattleMenuAttackOnly);
			for(int CaiCount = 0; CaiCount <1764; CaiCount++)
			{
				h_Sectors[CaiCount] = 13;
			}
			TurnOnPlaque("A to move\nS to Stay and End Turn\nESC to cancel");
		}
		return;
	}
	if(GetGameState() == MoveCursor || GetGameState() == MoveCursorDone)
	{
		for(int CaiCount = 0; CaiCount <1764; CaiCount++)
		{
			h_Sectors[CaiCount] = 13;
		}
		g_Cursor.SetSector(g_Cursor.GetPlayPTR()->GetSector());
		if(GetGameState() == MoveCursor)
		{
			SetGameState(BattleMenu);
			TurnOnPlaque("M to move\nA to attack\nESC to cancel");
		}
		else if(GetGameState() == MoveCursorDone)
		{
			SetGameState(BattleMenuMoveOnly);
			TurnOnPlaque("M to move\nESC to cancel");
		}
		return;
	}
	if(	GetGameState() == AttackDecide || GetGameState() == AttackDecideDone ||
		GetGameState() == MoveDecide || GetGameState() == MoveDecideDone)
	{
		TurnOffPlaque();
		switch(GetGameState())
		{
		case AttackDecide:
			SetGameState(AttackCursor);
			break;
		case AttackDecideDone:
			SetGameState(AttackCursorDone);
			break;
		case MoveDecide:
			SetGameState(MoveCursor);
			break;
		case MoveDecideDone:
			SetGameState(MoveCursorDone);
			break;
		}
	}
	if(GetGameState() == AttackRead || GetGameState() == AttackReadDone)
	{
		TurnOffPlaque();
		if(GetGameState() == AttackRead)
		{
			TurnOnPlaque("M to move\nESC to cancel");
			SetGameState(BattleMenuMoveOnly);
		}
		else if(GetGameState() == AttackReadDone)
		{
			SetGameState(PlayGame);
		}
		return;
	}
}

//////////////////////////////////////////////////////
// HandleEscape()
//////////////////////////////////////////////////////
void CEngine::HandleEscape()
{
    if (m_bMonsterAttacking || m_bAskingIfLoad || m_bAskingIfSave || 
        m_bAskingIfQuit || m_bPlayerDead) return;
    TurnOnPlaque(
"Don't forget to save your game.\n\n\
Are you sure you want\n\
to quit? (Y/N)");
    m_bAskingIfQuit = TRUE;
}

//////////////////////////////////////////////////////
// HandleN()
//////////////////////////////////////////////////////
void CEngine::HandleN()
{
    if (m_bAskingIfSave)
    {
        m_bAskingIfSave = FALSE;
        TurnOnPlaque("Game not saved.");
    }
    else if (m_bAskingIfLoad)
    {
        m_bAskingIfLoad = FALSE;
        TurnOnPlaque("Game not loaded.");
    }
    else if (m_bAskingIfQuit)
    {
        m_bAskingIfQuit = FALSE;
        TurnOffPlaque();
    }
}

//////////////////////////////////////////////////////
// HandleY()
//////////////////////////////////////////////////////
void CEngine::HandleY()
{
    if (m_bAskingIfSave)
    {
        m_bAskingIfSave = FALSE;
        SaveGame(TRUE);
        TurnOnPlaque("Game Saved");
    }
    else if (m_bAskingIfLoad)
    {
        m_bAskingIfLoad = FALSE;
        LoadGame();
        TurnOnPlaque("Game Loaded");
    }
    else if (m_bAskingIfQuit)
		m_Direct3D.CreateTitleScreenSurfaces();
        SetGameState(TitleScreen);
		SetStartGame(false);
		m_bAskingIfQuit = FALSE;
        TurnOffPlaque();
		m_Direct3D.CleanUpTrainingGrounds();
		g_Engine.GetCDirectSoundObj()->StopMusic(g_Engine.GetCDirectSoundObj()->GetCurrentlyPlaying());
		g_Engine.GetCDirectSoundObj()->PlayMusic(TitleScreenMusic);
}

//////////////////////////////////////////////////////
// DeleteTempFiles()
//////////////////////////////////////////////////////
void CEngine::DeleteTempFiles()
{
    char FileName[MAX_PATH];
    WIN32_FIND_DATA fileData;
    HANDLE fHandle = FindFirstFile("Temp\\*.*", &fileData);
    wsprintf(FileName, "Temp\\%s", fileData.cFileName);
    DeleteFile(FileName);
    while(FindNextFile(fHandle, &fileData))
    {
        wsprintf(FileName, "Temp\\%s", fileData.cFileName);
        DeleteFile(FileName);
    }
    FindClose(fHandle);
}

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
//////////////////////////////////////////////////////
// DeleteSaveFiles()
//////////////////////////////////////////////////////
void CEngine::DeleteSaveFiles()
{
    char FileName[MAX_PATH];
    WIN32_FIND_DATA fileData;
    HANDLE fHandle = FindFirstFile("Save\\*.*", &fileData);
    wsprintf(FileName, "Save\\%s", fileData.cFileName);
    DeleteFile(FileName);
    while(FindNextFile(fHandle, &fileData))
    {
        wsprintf(FileName, "Save\\%s", fileData.cFileName);
        DeleteFile(FileName);
    }
    FindClose(fHandle);
}
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//////////////////////////////////////////////////////
// CopySaveToTemp()
//////////////////////////////////////////////////////
void CEngine::CopySaveToTemp()
{
    char oldFileName[MAX_PATH];
    char newFileName[MAX_PATH];
    WIN32_FIND_DATA fileData;
    HANDLE fHandle = FindFirstFile("Save\\*.*", &fileData);
    wsprintf(newFileName, "Temp\\%s", fileData.cFileName);
    wsprintf(oldFileName, "Save\\%s", fileData.cFileName);
    CopyFile(oldFileName, newFileName, FALSE);
    while(FindNextFile(fHandle, &fileData))
    {
        wsprintf(newFileName, "Temp\\%s", fileData.cFileName);
        wsprintf(oldFileName, "Save\\%s", fileData.cFileName);
        CopyFile(oldFileName, newFileName, FALSE);
    }
    FindClose(fHandle);
}

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
//////////////////////////////////////////////////////
// CopyTempToSave()
//////////////////////////////////////////////////////
void CEngine::CopyTempToSave()
{
    char oldFileName[MAX_PATH];
    char newFileName[MAX_PATH];
    WIN32_FIND_DATA fileData;
    HANDLE fHandle = FindFirstFile("Temp\\*.*", &fileData);
    wsprintf(newFileName, "Save\\%s", fileData.cFileName);
    wsprintf(oldFileName, "Temp\\%s", fileData.cFileName);
    CopyFile(oldFileName, newFileName, FALSE);
    while(FindNextFile(fHandle, &fileData))
    {
        wsprintf(newFileName, "Save\\%s", fileData.cFileName);
        wsprintf(oldFileName, "Temp\\%s", fileData.cFileName);
        CopyFile(oldFileName, newFileName, FALSE);
    }
    FindClose(fHandle);
}

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//////////////////////////////////////////////////////
// GetCDirectSoundObj()
//////////////////////////////////////////////////////
CDirectSound* CEngine::GetCDirectSoundObj()
{
    return &m_Sound;
}

//////////////////////////////////////////////////////
// EndGame()
//////////////////////////////////////////////////////
void CEngine::EndGame()
{
    if (m_Player.GetHitPoints() <= 0)
    {
        m_bPlayerDead = TRUE;
        TurnOnPlaque("Jasper has died in battle.");
    }
}

//////////////////////////////////////////////////////
// HandleA()
//////////////////////////////////////////////////////
void CEngine::HandleA()
{
    if (m_bMonsterAttacking)
        AttackMonster();
    else
        DisplayAttributes();
}

//////////////////////////////////////////////////////
// HandleABattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleABattleMenu()
{
	TurnOffPlaque();
    if (GetGameState() == BattleMenu)
	{
		SetGameState(AttackCursor);
		attack_highlights();
	}
	else if(GetGameState() == BattleMenuAttackOnly)
	{
		SetGameState(AttackCursorDone);
		attack_highlights();
	}
}

//////////////////////////////////////////////////////
// HandleMBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleMBattleMenu()
{
    TurnOffPlaque();
    if (GetGameState() == BattleMenu)
	{
		SetGameState(MoveCursor);
		move_highlights();
	}
	else if(GetGameState() == BattleMenuMoveOnly)
	{
		SetGameState(MoveCursorDone);
		move_highlights();
	}
}

//////////////////////////////////////////////////////
// HandleSBattleMenu()
//////////////////////////////////////////////////////
void CEngine::HandleSBattleMenu()
{
	TurnOnPlaque("Set Facing:\n Adjust with Arrow Keys\nEnter to set");
	SetGameState(FacingDecide);
}
//////////////////////////////////////////////////////
// DisplayAttributes()
//////////////////////////////////////////////////////
void CEngine::DisplayAttributes()
{
    char msg[256];
    wsprintf(msg, 
"Hit Points: %d/%d\nExperience: %d\nLevel: %d\n\
Armor Level: %d\nWeapon Level: %d", 
        m_Player.GetHitPoints(), m_Player.GetMaxHitPoints(),
        m_Player.GetExperience(), m_Player.GetExperience()/100 + 1,
        m_Player.GetArmor(), m_Player.GetWeapon());
    TurnOnPlaque(msg);
}

//////////////////////////////////////////////////////
// ResetDirect3D()
//////////////////////////////////////////////////////
void CEngine::ResetDirect3D()
{
    m_Direct3D.CleanUpEverythingElse();
    m_Direct3D.InitD3D();
    if (m_bMonsterAttacking)
    {
        int iHPSave = m_pCurrentMonster->GetRemainingHitPoints();
        m_pCurrentMonster = GetBattleMap();
        m_pCurrentMonster->SetRemainingHitPoints(iHPSave);
    }
    switch (m_byMapType)
    {
    case TRAININGGROUNDS:
        m_Direct3D.SetCurrentTileSurface
            (m_Direct3D.GetTrainingGroundsSurfaces());
        break;
    }
}

//////////////////////////////////////////////////////
// SetPlayerDead()
//////////////////////////////////////////////////////
void CEngine::SetPlayerDead()
{
    m_bPlayerDead = TRUE;
}

//////////////////////////////////////////////////////
// ToggleMonsters()
//////////////////////////////////////////////////////
void CEngine::ToggleMonsters()
{
    if (!m_bNoMonsters)
    {
        m_bNoMonsters = TRUE;
        TurnOnPlaque("Monsters turned off.");
    }
    else
    {
        m_bNoMonsters = FALSE;
        TurnOnPlaque("Monsters turned on.");
    }
}

//////////////////////////////////////////////////////
// GetKeys()
//////////////////////////////////////////////////////
void CEngine::GetKeys()
{
    m_Player.SetKeys(10);
    TurnOnPlaque("10 free keys");
}

//////////////////////////////////////////////////////
// GetGold()
//////////////////////////////////////////////////////
void CEngine::GetGold()
{
    m_Player.SetGold(m_Player.GetGold() + 100);
    TurnOnPlaque("100 free gold");
}

//////////////////////////////////////////////////////
// GetExperience()
//////////////////////////////////////////////////////
void CEngine::GetExperience()
{
    m_Player.SetExperience(m_Player.GetExperience() + 100);
    TurnOnPlaque("100 free experience");
}


//////////////////////////////////////////////////////
// GetLife()
//////////////////////////////////////////////////////
void CEngine::GetHitPoints()
{
    m_Player.SetHitPoints(m_Player.GetHitPoints() + 10);
    TurnOnPlaque("10 free life");
}

//////////////////////////////////////////////////////
// HighlightMove()
//////////////////////////////////////////////////////
void CEngine::move_highlights()
{
	int iS, i1, play_move = 5;

	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		h_Sectors[CaiCount] = 0;
	}

	h_Sectors[m_Player.GetSector()] = play_move;

	for (i1 = play_move; i1 > 0; i1--)
	{
		for (iS = 0; iS < 1763; iS ++)
		{
			if(h_Sectors[iS] == i1)
			{
				//checking above
				// checking if above exists
				if(iS / MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS - MAPCOLUMNCOUNT] != 13 && a_Sectors[iS - MAPCOLUMNCOUNT] == 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS - MAPCOLUMNCOUNT] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS - MAPCOLUMNCOUNT] = i1 - 1;
						}
					}
				}
				//checking right
				// checking if right exists
				if((iS + 1) % MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS + 1] != 13 && a_Sectors[iS + 1] == 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS + 1] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS + 1] = i1 - 1;
						}
					}
				}
				//checking down
				// checking if Down exists
				if(iS / MAPCOLUMNCOUNT != 41)
				{
					// checking obstacles
					if(m_Sectors[iS + MAPCOLUMNCOUNT] != 13 && a_Sectors[iS + MAPCOLUMNCOUNT] == 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS + MAPCOLUMNCOUNT] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS + MAPCOLUMNCOUNT] = i1 - 1;
						}
					}
				}
				//checking left
				// checking if left exists
				if((iS) % MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS - 1] != 13 && a_Sectors[iS - 1] == 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS - 1] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS - 1] = i1 - 1;
						}
					}
				}
			}
		}
	}

	for (iS = 0; iS < 1763; iS++)
	{
		if(h_Sectors[iS] != 0)
		{
			h_Sectors[iS] = 16;
		}
		else
		{
			h_Sectors[iS] = 13;
		}
	}

	return;
}

//////////////////////////////////////////////////////
// HighlightAttack()
//////////////////////////////////////////////////////
void CEngine::attack_highlights()
{
	int iS, i1, play_max_attack = 5, play_min_attack = 1;

	for(int CaiCount = 0; CaiCount <1764; CaiCount++)
	{
		h_Sectors[CaiCount] = 0;
	}

	h_Sectors[m_Player.GetSector()] = play_max_attack;

	for (i1 = play_max_attack; i1 > 0; i1--)
	{
		for (iS = 0; iS < 1763; iS ++)
		{
			if(h_Sectors[iS] == i1)
			{
				//checking above
				// checking if above exists
				if(iS / MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS - MAPCOLUMNCOUNT] != 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS - MAPCOLUMNCOUNT] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS - MAPCOLUMNCOUNT] = i1 - 1;
						}
					}
				}
				//checking right
				// checking if right exists
				if((iS + 1) % MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS + 1] != 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS + 1] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS + 1] = i1 - 1;
						}
					}
				}
				//checking down
				// checking if Down exists
				if(iS / MAPCOLUMNCOUNT != 41)
				{
					// checking obstacles
					if(m_Sectors[iS + MAPCOLUMNCOUNT] != 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS + MAPCOLUMNCOUNT] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS + MAPCOLUMNCOUNT] = i1 - 1;
						}
					}
				}
				//checking left
				// checking if left exists
				if((iS) % MAPCOLUMNCOUNT != 0)
				{
					// checking obstacles
					if(m_Sectors[iS - 1] != 13)
					{
						//checking if higher values assigned
						if(h_Sectors[iS - 1] < h_Sectors[iS] - 1)
						{
							h_Sectors[iS - 1] = i1 - 1;
						}
					}
				}
			}
		}
	}

	for (iS = 0; iS < 1763; iS++)
	{
		if(h_Sectors[iS] > (play_max_attack - play_min_attack))
		{
			h_Sectors[iS] = 0;
		}
	}

	for (iS = 0; iS < 1763; iS++)
	{
		if(h_Sectors[iS] != 0)
		{
			h_Sectors[iS] = 16;
		}
		else
		{
			h_Sectors[iS] = 13;
		}
	}

	return;
}